LLVM 24.0.0git
ARMISelLowering.cpp
Go to the documentation of this file.
1//===- ARMISelLowering.cpp - ARM DAG Lowering Implementation --------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines the interfaces that ARM uses to lower LLVM code into a
10// selection DAG.
11//
12//===----------------------------------------------------------------------===//
13
14#include "ARMISelLowering.h"
15#include "ARMBaseInstrInfo.h"
16#include "ARMBaseRegisterInfo.h"
17#include "ARMCallingConv.h"
20#include "ARMPerfectShuffle.h"
21#include "ARMRegisterInfo.h"
22#include "ARMSelectionDAGInfo.h"
23#include "ARMSubtarget.h"
27#include "Utils/ARMBaseInfo.h"
28#include "llvm/ADT/APFloat.h"
29#include "llvm/ADT/APInt.h"
30#include "llvm/ADT/ArrayRef.h"
31#include "llvm/ADT/BitVector.h"
32#include "llvm/ADT/DenseMap.h"
33#include "llvm/ADT/STLExtras.h"
36#include "llvm/ADT/Statistic.h"
38#include "llvm/ADT/StringRef.h"
40#include "llvm/ADT/Twine.h"
66#include "llvm/IR/Attributes.h"
67#include "llvm/IR/CallingConv.h"
68#include "llvm/IR/Constant.h"
69#include "llvm/IR/Constants.h"
70#include "llvm/IR/DataLayout.h"
71#include "llvm/IR/DebugLoc.h"
73#include "llvm/IR/Function.h"
74#include "llvm/IR/GlobalAlias.h"
75#include "llvm/IR/GlobalValue.h"
77#include "llvm/IR/IRBuilder.h"
78#include "llvm/IR/InlineAsm.h"
79#include "llvm/IR/Instruction.h"
82#include "llvm/IR/Intrinsics.h"
83#include "llvm/IR/IntrinsicsARM.h"
84#include "llvm/IR/Module.h"
85#include "llvm/IR/Type.h"
86#include "llvm/IR/User.h"
87#include "llvm/IR/Value.h"
88#include "llvm/MC/MCInstrDesc.h"
90#include "llvm/MC/MCSchedule.h"
97#include "llvm/Support/Debug.h"
105#include <algorithm>
106#include <cassert>
107#include <cstdint>
108#include <iterator>
109#include <limits>
110#include <optional>
111#include <tuple>
112#include <utility>
113#include <vector>
114
115using namespace llvm;
116
117#define DEBUG_TYPE "arm-isel"
118
119STATISTIC(NumTailCalls, "Number of tail calls");
120STATISTIC(NumOptimizedImms, "Number of times immediates were optimized");
121STATISTIC(NumMovwMovt, "Number of GAs materialized with movw + movt");
122STATISTIC(NumLoopByVals, "Number of loops generated for byval arguments");
123STATISTIC(NumConstpoolPromoted,
124 "Number of constants with their storage promoted into constant pools");
125
126static cl::opt<bool>
127ARMInterworking("arm-interworking", cl::Hidden,
128 cl::desc("Enable / disable ARM interworking (for debugging only)"),
129 cl::init(true));
130
132 "arm-promote-constant", cl::Hidden,
133 cl::desc("Enable / disable promotion of unnamed_addr constants into "
134 "constant pools"),
135 cl::init(false)); // FIXME: set to true by default once PR32780 is fixed
137 "arm-promote-constant-max-size", cl::Hidden,
138 cl::desc("Maximum size of constant to promote into a constant pool"),
139 cl::init(64));
141 "arm-promote-constant-max-total", cl::Hidden,
142 cl::desc("Maximum size of ALL constants to promote into a constant pool"),
143 cl::init(128));
144
146MVEMaxSupportedInterleaveFactor("mve-max-interleave-factor", cl::Hidden,
147 cl::desc("Maximum interleave factor for MVE VLDn to generate."),
148 cl::init(2));
149
151 "arm-max-base-updates-to-check", cl::Hidden,
152 cl::desc("Maximum number of base-updates to check generating postindex."),
153 cl::init(64));
154
155/// Value type used for "flags" operands / results (either CPSR or FPSCR_NZCV).
156constexpr MVT FlagsVT = MVT::i32;
157
158// The APCS parameter registers.
159static const MCPhysReg GPRArgRegs[] = {
160 ARM::R0, ARM::R1, ARM::R2, ARM::R3
161};
162
164 SelectionDAG &DAG, const SDLoc &DL) {
166 assert(Arg.ArgVT.bitsLT(MVT::i32));
167 SDValue Trunc = DAG.getNode(ISD::TRUNCATE, DL, Arg.ArgVT, Value);
168 SDValue Ext =
170 MVT::i32, Trunc);
171 return Ext;
172}
173
174void ARMTargetLowering::addTypeForNEON(MVT VT, MVT PromotedLdStVT) {
175 if (VT != PromotedLdStVT) {
177 AddPromotedToType (ISD::LOAD, VT, PromotedLdStVT);
178
180 AddPromotedToType (ISD::STORE, VT, PromotedLdStVT);
181 }
182
183 MVT ElemTy = VT.getVectorElementType();
184 if (ElemTy != MVT::f64)
188 if (ElemTy == MVT::i32) {
193 } else {
198 }
207 if (VT.isInteger()) {
211 }
212
213 // Neon does not support vector divide/remainder operations.
222
223 if (!VT.isFloatingPoint() && VT != MVT::v2i64 && VT != MVT::v1i64)
224 for (auto Opcode : {ISD::ABS, ISD::ABDS, ISD::ABDU, ISD::SMIN, ISD::SMAX,
226 setOperationAction(Opcode, VT, Legal);
227 if (!VT.isFloatingPoint())
228 for (auto Opcode : {ISD::SADDSAT, ISD::UADDSAT, ISD::SSUBSAT, ISD::USUBSAT})
229 setOperationAction(Opcode, VT, Legal);
230}
231
232void ARMTargetLowering::addDRTypeForNEON(MVT VT) {
233 addRegisterClass(VT, &ARM::DPRRegClass);
234 addTypeForNEON(VT, MVT::f64);
235}
236
237void ARMTargetLowering::addQRTypeForNEON(MVT VT) {
238 addRegisterClass(VT, &ARM::DPairRegClass);
239 addTypeForNEON(VT, MVT::v2f64);
240}
241
242void ARMTargetLowering::setAllExpand(MVT VT) {
243 for (unsigned Opc = 0; Opc < ISD::BUILTIN_OP_END; ++Opc)
245
246 // We support these really simple operations even on types where all
247 // the actual arithmetic has to be broken down into simpler
248 // operations or turned into library calls.
253}
254
255void ARMTargetLowering::addAllExtLoads(const MVT From, const MVT To,
256 LegalizeAction Action) {
257 setLoadExtAction(ISD::EXTLOAD, From, To, Action);
258 setLoadExtAction(ISD::ZEXTLOAD, From, To, Action);
259 setLoadExtAction(ISD::SEXTLOAD, From, To, Action);
260}
261
262void ARMTargetLowering::addMVEVectorTypes(bool HasMVEFP) {
263 const MVT IntTypes[] = { MVT::v16i8, MVT::v8i16, MVT::v4i32 };
264
265 for (auto VT : IntTypes) {
266 addRegisterClass(VT, &ARM::MQPRRegClass);
297
298 // No native support for these.
308
309 // Vector reductions
319
320 if (!HasMVEFP) {
325 } else {
328 }
329
330 // Pre and Post inc are supported on loads and stores
331 for (unsigned im = (unsigned)ISD::PRE_INC;
332 im != (unsigned)ISD::LAST_INDEXED_MODE; ++im) {
337 }
338 }
339
340 const MVT FloatTypes[] = { MVT::v8f16, MVT::v4f32 };
341 for (auto VT : FloatTypes) {
342 addRegisterClass(VT, &ARM::MQPRRegClass);
343 if (!HasMVEFP)
344 setAllExpand(VT);
345
346 // These are legal or custom whether we have MVE.fp or not
359
360 // Pre and Post inc are supported on loads and stores
361 for (unsigned im = (unsigned)ISD::PRE_INC;
362 im != (unsigned)ISD::LAST_INDEXED_MODE; ++im) {
367 }
368
369 if (HasMVEFP) {
377 }
382
383 // No native support for these.
398 }
399 }
400
401 // Custom Expand smaller than legal vector reductions to prevent false zero
402 // items being added.
411
412 // We 'support' these types up to bitcast/load/store level, regardless of
413 // MVE integer-only / float support. Only doing FP data processing on the FP
414 // vector types is inhibited at integer-only level.
415 const MVT LongTypes[] = { MVT::v2i64, MVT::v2f64 };
416 for (auto VT : LongTypes) {
417 addRegisterClass(VT, &ARM::MQPRRegClass);
418 setAllExpand(VT);
424 }
426
427 // We can do bitwise operations on v2i64 vectors
428 setOperationAction(ISD::AND, MVT::v2i64, Legal);
429 setOperationAction(ISD::OR, MVT::v2i64, Legal);
430 setOperationAction(ISD::XOR, MVT::v2i64, Legal);
431
432 // It is legal to extload from v4i8 to v4i16 or v4i32.
433 addAllExtLoads(MVT::v8i16, MVT::v8i8, Legal);
434 addAllExtLoads(MVT::v4i32, MVT::v4i16, Legal);
435 addAllExtLoads(MVT::v4i32, MVT::v4i8, Legal);
436
437 // It is legal to sign extend from v4i8/v4i16 to v4i32 or v8i8 to v8i16.
443
444 // Some truncating stores are legal too.
445 setTruncStoreAction(MVT::v4i32, MVT::v4i16, Legal);
446 setTruncStoreAction(MVT::v4i32, MVT::v4i8, Legal);
447 setTruncStoreAction(MVT::v8i16, MVT::v8i8, Legal);
448
449 // Pre and Post inc on these are legal, given the correct extends
450 for (unsigned im = (unsigned)ISD::PRE_INC;
451 im != (unsigned)ISD::LAST_INDEXED_MODE; ++im) {
452 for (auto VT : {MVT::v8i8, MVT::v4i8, MVT::v4i16}) {
457 }
458 }
459
460 // Predicate types
461 const MVT pTypes[] = {MVT::v16i1, MVT::v8i1, MVT::v4i1, MVT::v2i1};
462 for (auto VT : pTypes) {
463 addRegisterClass(VT, &ARM::VCCRRegClass);
478
479 if (!HasMVEFP) {
484 }
485 }
489 setOperationAction(ISD::OR, MVT::v2i1, Expand);
495
504}
505
507 return static_cast<const ARMBaseTargetMachine &>(getTargetMachine());
508}
509
511 const ARMSubtarget &STI)
512 : TargetLowering(TM_, STI), Subtarget(&STI),
513 RegInfo(Subtarget->getRegisterInfo()),
514 Itins(Subtarget->getInstrItineraryData()) {
515 const auto &TM = static_cast<const ARMBaseTargetMachine &>(TM_);
516
519
520 const Triple &TT = TM.getTargetTriple();
521
522 if (Subtarget->isThumb1Only())
523 addRegisterClass(MVT::i32, &ARM::tGPRRegClass);
524 else
525 addRegisterClass(MVT::i32, &ARM::GPRRegClass);
526
527 if (!Subtarget->useSoftFloat() && !Subtarget->isThumb1Only() &&
528 Subtarget->hasFPRegs()) {
529 addRegisterClass(MVT::f32, &ARM::SPRRegClass);
530 addRegisterClass(MVT::f64, &ARM::DPRRegClass);
531
532 if (!Subtarget->hasVFP2Base()) {
533 setAllExpand(MVT::f32);
534 } else {
537
540 setOperationAction(Op, MVT::f32, Legal);
541 }
542 if (!Subtarget->hasFP64()) {
543 setAllExpand(MVT::f64);
544 } else {
547 setOperationAction(Op, MVT::f64, Legal);
548
550 }
551 }
552
553 if (Subtarget->hasFullFP16()) {
556 setOperationAction(Op, MVT::f16, Legal);
557
558 addRegisterClass(MVT::f16, &ARM::HPRRegClass);
561
566 }
567
568 if (Subtarget->hasBF16()) {
569 addRegisterClass(MVT::bf16, &ARM::HPRRegClass);
570 setAllExpand(MVT::bf16);
571 if (!Subtarget->hasFullFP16())
575 } else {
580 }
581
583 for (MVT InnerVT : MVT::fixedlen_vector_valuetypes()) {
584 setTruncStoreAction(VT, InnerVT, Expand);
585 addAllExtLoads(VT, InnerVT, Expand);
586 }
587
590
592 }
593
594 if (!Subtarget->isThumb1Only() && !Subtarget->hasV8_1MMainlineOps())
596
597 if (!Subtarget->hasV8_1MMainlineOps())
599
600 if (!Subtarget->isThumb1Only())
602
605
608
609 if (Subtarget->hasMVEIntegerOps())
610 addMVEVectorTypes(Subtarget->hasMVEFloatOps());
611
612 // Combine low-overhead loop intrinsics so that we can lower i1 types.
613 if (Subtarget->hasLOB()) {
615 }
616
617 if (Subtarget->hasNEON()) {
618 addDRTypeForNEON(MVT::v2f32);
619 addDRTypeForNEON(MVT::v8i8);
620 addDRTypeForNEON(MVT::v4i16);
621 addDRTypeForNEON(MVT::v2i32);
622 addDRTypeForNEON(MVT::v1i64);
623
624 addQRTypeForNEON(MVT::v4f32);
625 addQRTypeForNEON(MVT::v2f64);
626 addQRTypeForNEON(MVT::v16i8);
627 addQRTypeForNEON(MVT::v8i16);
628 addQRTypeForNEON(MVT::v4i32);
629 addQRTypeForNEON(MVT::v2i64);
630
631 if (Subtarget->hasFullFP16()) {
632 addQRTypeForNEON(MVT::v8f16);
633 addDRTypeForNEON(MVT::v4f16);
634 }
635
636 if (Subtarget->hasBF16()) {
637 addQRTypeForNEON(MVT::v8bf16);
638 addDRTypeForNEON(MVT::v4bf16);
639 }
640 }
641
642 if (Subtarget->hasMVEIntegerOps() || Subtarget->hasNEON()) {
643 // v2f64 is legal so that QR subregs can be extracted as f64 elements, but
644 // none of Neon, MVE or VFP supports any arithmetic operations on it.
645 setOperationAction(ISD::FADD, MVT::v2f64, Expand);
646 setOperationAction(ISD::FSUB, MVT::v2f64, Expand);
647 setOperationAction(ISD::FMUL, MVT::v2f64, Expand);
648 // FIXME: Code duplication: FDIV and FREM are expanded always, see
649 // ARMTargetLowering::addTypeForNEON method for details.
650 setOperationAction(ISD::FDIV, MVT::v2f64, Expand);
651 setOperationAction(ISD::FREM, MVT::v2f64, Expand);
652 // FIXME: Create unittest.
653 // In another words, find a way when "copysign" appears in DAG with vector
654 // operands.
656 // FIXME: Code duplication: SETCC has custom operation action, see
657 // ARMTargetLowering::addTypeForNEON method for details.
659 // FIXME: Create unittest for FNEG and for FABS.
660 setOperationAction(ISD::FNEG, MVT::v2f64, Expand);
661 setOperationAction(ISD::FABS, MVT::v2f64, Expand);
663 setOperationAction(ISD::FSIN, MVT::v2f64, Expand);
664 setOperationAction(ISD::FCOS, MVT::v2f64, Expand);
665 setOperationAction(ISD::FTAN, MVT::v2f64, Expand);
666 setOperationAction(ISD::FPOW, MVT::v2f64, Expand);
667 setOperationAction(ISD::FLOG, MVT::v2f64, Expand);
670 setOperationAction(ISD::FEXP, MVT::v2f64, Expand);
679 setOperationAction(ISD::FMA, MVT::v2f64, Expand);
680 }
681
682 if (Subtarget->hasNEON()) {
683 // The same with v4f32. But keep in mind that vadd, vsub, vmul are natively
684 // supported for v4f32.
686 setOperationAction(ISD::FSIN, MVT::v4f32, Expand);
687 setOperationAction(ISD::FCOS, MVT::v4f32, Expand);
688 setOperationAction(ISD::FTAN, MVT::v4f32, Expand);
689 setOperationAction(ISD::FPOW, MVT::v4f32, Expand);
690 setOperationAction(ISD::FLOG, MVT::v4f32, Expand);
693 setOperationAction(ISD::FEXP, MVT::v4f32, Expand);
702
703 // Mark v2f32 intrinsics.
705 setOperationAction(ISD::FSIN, MVT::v2f32, Expand);
706 setOperationAction(ISD::FCOS, MVT::v2f32, Expand);
707 setOperationAction(ISD::FTAN, MVT::v2f32, Expand);
708 setOperationAction(ISD::FPOW, MVT::v2f32, Expand);
709 setOperationAction(ISD::FLOG, MVT::v2f32, Expand);
712 setOperationAction(ISD::FEXP, MVT::v2f32, Expand);
721
724 setOperationAction(Op, MVT::v4f16, Expand);
725 setOperationAction(Op, MVT::v8f16, Expand);
726 }
727
728 // Neon does not support some operations on v1i64 and v2i64 types.
729 setOperationAction(ISD::MUL, MVT::v1i64, Expand);
730 // Custom handling for some quad-vector types to detect VMULL.
731 setOperationAction(ISD::MUL, MVT::v8i16, Custom);
732 setOperationAction(ISD::MUL, MVT::v4i32, Custom);
733 setOperationAction(ISD::MUL, MVT::v2i64, Custom);
734 // Custom handling for some vector types to avoid expensive expansions
735 setOperationAction(ISD::SDIV, MVT::v4i16, Custom);
737 setOperationAction(ISD::UDIV, MVT::v4i16, Custom);
739 // Neon does not have single instruction SINT_TO_FP and UINT_TO_FP with
740 // a destination type that is wider than the source, and nor does
741 // it have a FP_TO_[SU]INT instruction with a narrower destination than
742 // source.
751
754
755 // NEON does not have single instruction CTPOP for vectors with element
756 // types wider than 8-bits. However, custom lowering can leverage the
757 // v8i8/v16i8 vcnt instruction.
764
765 setOperationAction(ISD::CTLZ, MVT::v1i64, Expand);
766 setOperationAction(ISD::CTLZ, MVT::v2i64, Expand);
767
768 // NEON does not have single instruction CTTZ for vectors.
770 setOperationAction(ISD::CTTZ, MVT::v4i16, Custom);
771 setOperationAction(ISD::CTTZ, MVT::v2i32, Custom);
772 setOperationAction(ISD::CTTZ, MVT::v1i64, Custom);
773
774 setOperationAction(ISD::CTTZ, MVT::v16i8, Custom);
775 setOperationAction(ISD::CTTZ, MVT::v8i16, Custom);
776 setOperationAction(ISD::CTTZ, MVT::v4i32, Custom);
777 setOperationAction(ISD::CTTZ, MVT::v2i64, Custom);
778
783
788
792 }
793
794 // NEON only has FMA instructions as of VFP4.
795 if (!Subtarget->hasVFP4Base()) {
796 setOperationAction(ISD::FMA, MVT::v2f32, Expand);
797 setOperationAction(ISD::FMA, MVT::v4f32, Expand);
798 }
799
802
803 // It is legal to extload from v4i8 to v4i16 or v4i32.
804 for (MVT Ty : {MVT::v8i8, MVT::v4i8, MVT::v2i8, MVT::v4i16, MVT::v2i16,
805 MVT::v2i32}) {
810 }
811 }
812
813 for (auto VT : {MVT::v8i8, MVT::v4i16, MVT::v2i32, MVT::v16i8, MVT::v8i16,
814 MVT::v4i32}) {
819 }
820 }
821
822 if (Subtarget->hasNEON() || Subtarget->hasMVEIntegerOps()) {
829 }
830 if (Subtarget->hasMVEIntegerOps()) {
833 ISD::SETCC});
834 }
835 if (Subtarget->hasMVEFloatOps()) {
837 }
838
839 if (!Subtarget->hasFP64()) {
840 // When targeting a floating-point unit with only single-precision
841 // operations, f64 is legal for the few double-precision instructions which
842 // are present However, no double-precision operations other than moves,
843 // loads and stores are provided by the hardware.
880 }
881
882 // STRICT_(U/S)INT_TO_FP specifically use the input MVT to register with
883 // setOperationAction() as opposed to other opcodes that use the output MVT
884 // All inputs should be i32 due to type legalization
887
890
891 if (!Subtarget->hasFP64() || !Subtarget->hasFPARMv8Base()) {
894 if (Subtarget->hasFullFP16()) {
897 }
898 } else {
900 }
901
902 if (!Subtarget->hasFP16()) {
905 } else {
908 }
909
910 computeRegisterProperties(Subtarget->getRegisterInfo());
911
912 // ARM does not have floating-point extending loads.
913 for (MVT VT : MVT::fp_valuetypes()) {
914 setLoadExtAction(ISD::EXTLOAD, VT, MVT::f32, Expand);
915 setLoadExtAction(ISD::EXTLOAD, VT, MVT::f16, Expand);
916 setLoadExtAction(ISD::EXTLOAD, VT, MVT::bf16, Expand);
917 }
918
919 // ... or truncating stores
920 setTruncStoreAction(MVT::f64, MVT::f32, Expand);
921 setTruncStoreAction(MVT::f32, MVT::f16, Expand);
922 setTruncStoreAction(MVT::f64, MVT::f16, Expand);
923 setTruncStoreAction(MVT::f32, MVT::bf16, Expand);
924 setTruncStoreAction(MVT::f64, MVT::bf16, Expand);
925
926 // ARM does not have i1 sign extending load.
927 for (MVT VT : MVT::integer_valuetypes())
929
930 // ARM supports all 4 flavors of integer indexed load / store.
931 if (!Subtarget->isThumb1Only()) {
932 for (unsigned im = (unsigned)ISD::PRE_INC;
934 setIndexedLoadAction(im, MVT::i1, Legal);
935 setIndexedLoadAction(im, MVT::i8, Legal);
936 setIndexedLoadAction(im, MVT::i16, Legal);
937 setIndexedLoadAction(im, MVT::i32, Legal);
938 setIndexedStoreAction(im, MVT::i1, Legal);
939 setIndexedStoreAction(im, MVT::i8, Legal);
940 setIndexedStoreAction(im, MVT::i16, Legal);
941 setIndexedStoreAction(im, MVT::i32, Legal);
942 }
943 } else {
944 // Thumb-1 has limited post-inc load/store support - LDM r0!, {r1}.
947 }
948
949 // Custom loads/stores to possible use __aeabi_uread/write*
950 if (TT.isTargetAEABI() && !Subtarget->allowsUnalignedMem()) {
955 }
956
961
962 if (!Subtarget->isThumb1Only()) {
965 }
966
971 if (Subtarget->hasDSP()) {
980 }
981 if (Subtarget->hasBaseDSP()) {
984 }
985
986 // i64 operation support.
989 if (Subtarget->isThumb1Only()) {
992 }
993 if (Subtarget->isThumb1Only() || !Subtarget->hasV6Ops()
994 || (Subtarget->isThumb2() && !Subtarget->hasDSP()))
996
1006
1007 // MVE lowers 64 bit shifts to lsll and lsrl
1008 // assuming that ISD::SRL and SRA of i64 are already marked custom
1009 if (Subtarget->hasMVEIntegerOps())
1011
1012 // Expand to __aeabi_l{lsl,lsr,asr} calls for Thumb1.
1013 if (Subtarget->isThumb1Only()) {
1017 }
1018
1019 if (!Subtarget->isThumb1Only() && Subtarget->hasV6T2Ops())
1021
1022 // ARM does not have ROTL.
1027 }
1029 // TODO: These two should be set to LibCall, but this currently breaks
1030 // the Linux kernel build. See #101786.
1033 if (!Subtarget->hasV5TOps() || Subtarget->isThumb1Only()) {
1036 }
1037
1038 // @llvm.readcyclecounter requires the Performance Monitors extension.
1039 // Default to the 0 expansion on unsupported platforms.
1040 // FIXME: Technically there are older ARM CPUs that have
1041 // implementation-specific ways of obtaining this information.
1042 if (Subtarget->hasPerfMon())
1044
1045 // Only ARMv6 has BSWAP.
1046 if (!Subtarget->hasV6Ops())
1048
1049 bool hasDivide = Subtarget->isThumb() ? Subtarget->hasDivideInThumbMode()
1050 : Subtarget->hasDivideInARMMode();
1051 if (!hasDivide) {
1052 // These are expanded into libcalls if the cpu doesn't have HW divider.
1055 }
1056
1057 if (TT.isOSWindows() && !Subtarget->hasDivideInThumbMode()) {
1060
1063 }
1064
1067
1068 // Register based DivRem for AEABI (RTABI 4.2)
1069 if (TT.isTargetAEABI() || TT.isAndroid() || TT.isTargetGNUAEABI() ||
1070 TT.isTargetMuslAEABI() || TT.isOSFuchsia() || TT.isOSWindows()) {
1073 HasStandaloneRem = false;
1074
1079 } else {
1082 }
1083
1088
1089 setOperationAction(ISD::TRAP, MVT::Other, Legal);
1091
1092 // Use the default implementation.
1094 setOperationAction(ISD::VAARG, MVT::Other, Expand);
1096 setOperationAction(ISD::VAEND, MVT::Other, Expand);
1099
1100 if (TT.isOSWindows())
1102 else
1104
1105 // ARMv6 Thumb1 (except for CPUs that support dmb / dsb) and earlier use
1106 // the default expansion.
1107 InsertFencesForAtomic = false;
1108 if (Subtarget->hasAnyDataBarrier() &&
1109 (!Subtarget->isThumb() || Subtarget->hasV8MBaselineOps())) {
1110 // ATOMIC_FENCE needs custom lowering; the others should have been expanded
1111 // to ldrex/strex loops already.
1113 if (!Subtarget->isThumb() || !Subtarget->isMClass())
1115
1116 // On v8, we have particularly efficient implementations of atomic fences
1117 // if they can be combined with nearby atomic loads and stores.
1118 if (!Subtarget->hasAcquireRelease() ||
1119 getTargetMachine().getOptLevel() == CodeGenOptLevel::None) {
1120 // Automatically insert fences (dmb ish) around ATOMIC_SWAP etc.
1121 InsertFencesForAtomic = true;
1122 }
1123 } else {
1124 // If there's anything we can use as a barrier, go through custom lowering
1125 // for ATOMIC_FENCE.
1126 // If target has DMB in thumb, Fences can be inserted.
1127 if (Subtarget->hasDataBarrier())
1128 InsertFencesForAtomic = true;
1129
1131 Subtarget->hasAnyDataBarrier() ? Custom : Expand);
1132
1133 // Set them all for libcall, which will force libcalls.
1146 // Mark ATOMIC_LOAD and ATOMIC_STORE custom so we can handle the
1147 // Unordered/Monotonic case.
1148 if (!InsertFencesForAtomic) {
1151 }
1152 }
1153
1154 // Compute supported atomic widths.
1155 if (TT.isOSLinux() || (!Subtarget->isMClass() && Subtarget->hasV6Ops())) {
1156 // For targets where __sync_* routines are reliably available, we use them
1157 // if necessary.
1158 //
1159 // ARM Linux always supports 64-bit atomics through kernel-assisted atomic
1160 // routines (kernel 3.1 or later). FIXME: Not with compiler-rt?
1161 //
1162 // ARMv6 targets have native instructions in ARM mode. For Thumb mode,
1163 // such targets should provide __sync_* routines, which use the ARM mode
1164 // instructions. (ARMv6 doesn't have dmb, but it has an equivalent
1165 // encoding; see ARMISD::MEMBARRIER_MCR.)
1167 } else if ((Subtarget->isMClass() && Subtarget->hasV8MBaselineOps()) ||
1168 Subtarget->hasForced32BitAtomics()) {
1169 // Cortex-M (besides Cortex-M0) have 32-bit atomics.
1171 } else {
1172 // We can't assume anything about other targets; just use libatomic
1173 // routines.
1175 }
1176
1178
1180
1181 // Requires SXTB/SXTH, available on v6 and up in both ARM and Thumb modes.
1182 if (!Subtarget->hasV6Ops()) {
1185 }
1187
1188 if (!Subtarget->useSoftFloat() && Subtarget->hasFPRegs() &&
1189 !Subtarget->isThumb1Only()) {
1190 // Turn f64->i64 into VMOVRRD, i64 -> f64 to VMOVDRR
1191 // iff target supports vfp2.
1201 }
1202
1203 // We want to custom lower some of our intrinsics.
1208
1218 if (Subtarget->hasFullFP16()) {
1222 }
1223
1225
1228 if (Subtarget->hasFullFP16())
1232 setOperationAction(ISD::BR_JT, MVT::Other, Custom);
1233
1234 // We don't support sin/cos/fmod/copysign/pow
1243 if (!Subtarget->useSoftFloat() && Subtarget->hasVFP2Base() &&
1244 !Subtarget->isThumb1Only()) {
1247 }
1250
1251 if (!Subtarget->hasVFP4Base()) {
1254 }
1255
1256 // Various VFP goodness
1257 if (!Subtarget->useSoftFloat() && !Subtarget->isThumb1Only()) {
1258 // FP-ARMv8 adds f64 <-> f16 conversion. Before that it should be expanded.
1259 if (!Subtarget->hasFPARMv8Base() || !Subtarget->hasFP64()) {
1264 }
1265
1266 // fp16 is a special v7 extension that adds f16 <-> f32 conversions.
1267 if (!Subtarget->hasFP16()) {
1272 }
1273
1274 // Strict floating-point comparisons need custom lowering.
1281 }
1282
1283 // FP-ARMv8 implements a lot of rounding-like FP operations.
1284 if (Subtarget->hasFPARMv8Base()) {
1285 for (auto Op :
1292 setOperationAction(Op, MVT::f32, Legal);
1293
1294 if (Subtarget->hasFP64())
1295 setOperationAction(Op, MVT::f64, Legal);
1296 }
1297
1298 if (Subtarget->hasNEON()) {
1303 }
1304 }
1305
1306 // FP16 often need to be promoted to call lib functions
1307 // clang-format off
1308 if (Subtarget->hasFullFP16()) {
1312
1313 for (auto Op : {ISD::FREM, ISD::FPOW, ISD::FPOWI,
1327 setOperationAction(Op, MVT::f16, Promote);
1328 }
1329
1330 // Round-to-integer need custom lowering for fp16, as Promote doesn't work
1331 // because the result type is integer.
1333 setOperationAction(Op, MVT::f16, Custom);
1334
1340 setOperationAction(Op, MVT::f16, Legal);
1341 }
1342 // clang-format on
1343 }
1344
1345 if (Subtarget->hasNEON()) {
1346 // vmin and vmax aren't available in a scalar form, so we can use
1347 // a NEON instruction with an undef lane instead.
1356
1357 if (Subtarget->hasV8Ops()) {
1362 setOperationAction(Op, MVT::v2f32, Legal);
1363 setOperationAction(Op, MVT::v4f32, Legal);
1364 }
1365 }
1366
1367 if (Subtarget->hasFullFP16()) {
1372
1377
1382 setOperationAction(Op, MVT::v4f16, Legal);
1383 setOperationAction(Op, MVT::v8f16, Legal);
1384 }
1385 }
1386 }
1387
1388 // On MSVC, both 32-bit and 64-bit, ldexpf(f32) is not defined. MinGW has
1389 // it, but it's just a wrapper around ldexp.
1390 if (TT.isOSWindows()) {
1392 if (isOperationExpand(Op, MVT::f32))
1393 setOperationAction(Op, MVT::f32, Promote);
1394 }
1395
1396 // LegalizeDAG currently can't expand fp16 LDEXP/FREXP on targets where i16
1397 // isn't legal.
1399 if (isOperationExpand(Op, MVT::f16))
1400 setOperationAction(Op, MVT::f16, Promote);
1401
1402 // We have target-specific dag combine patterns for the following nodes:
1403 // ARMISD::VMOVRRD - No need to call setTargetDAGCombine
1406
1407 if (Subtarget->hasMVEIntegerOps())
1409
1410 if (Subtarget->hasV6Ops())
1412 if (Subtarget->isThumb1Only())
1414 // Attempt to lower smin/smax to ssat/usat
1415 if ((!Subtarget->isThumb() && Subtarget->hasV6Ops()) ||
1416 Subtarget->isThumb2()) {
1418 }
1419
1421
1422 if (Subtarget->useSoftFloat() || Subtarget->isThumb1Only() ||
1423 !Subtarget->hasVFP2Base() || Subtarget->hasMinSize())
1425 else
1427
1428 //// temporary - rewrite interface to use type
1431 MaxStoresPerMemcpy = 4; // For @llvm.memcpy -> sequence of stores
1433 MaxStoresPerMemmove = 4; // For @llvm.memmove -> sequence of stores
1435
1436 // On ARM arguments smaller than 4 bytes are extended, so all arguments
1437 // are at least 4 bytes aligned.
1439
1440 // Prefer likely predicted branches to selects on out-of-order cores.
1441 PredictableSelectIsExpensive = Subtarget->getSchedModel().isOutOfOrder();
1442
1443 setPrefLoopAlignment(Align(1ULL << Subtarget->getPreferBranchLogAlignment()));
1445 Align(1ULL << Subtarget->getPreferBranchLogAlignment()));
1446
1447 setMinFunctionAlignment(Subtarget->isThumb() ? Align(2) : Align(4));
1448
1449 IsStrictFPEnabled = true;
1450}
1451
1453 return Subtarget->useSoftFloat();
1454}
1455
1457 return !Subtarget->isThumb1Only() && VT.getSizeInBits() <= 32;
1458}
1459
1460// FIXME: It might make sense to define the representative register class as the
1461// nearest super-register that has a non-null superset. For example, DPR_VFP2 is
1462// a super-register of SPR, and DPR is a superset if DPR_VFP2. Consequently,
1463// SPR's representative would be DPR_VFP2. This should work well if register
1464// pressure tracking were modified such that a register use would increment the
1465// pressure of the register class's representative and all of it's super
1466// classes' representatives transitively. We have not implemented this because
1467// of the difficulty prior to coalescing of modeling operand register classes
1468// due to the common occurrence of cross class copies and subregister insertions
1469// and extractions.
1470std::pair<const TargetRegisterClass *, uint8_t>
1472 MVT VT) const {
1473 const TargetRegisterClass *RRC = nullptr;
1474 uint8_t Cost = 1;
1475 switch (VT.SimpleTy) {
1476 default:
1478 // Use DPR as representative register class for all floating point
1479 // and vector types. Since there are 32 SPR registers and 32 DPR registers so
1480 // the cost is 1 for both f32 and f64.
1481 case MVT::f32: case MVT::f64: case MVT::v8i8: case MVT::v4i16:
1482 case MVT::v2i32: case MVT::v1i64: case MVT::v2f32:
1483 RRC = &ARM::DPRRegClass;
1484 // When NEON is used for SP, only half of the register file is available
1485 // because operations that define both SP and DP results will be constrained
1486 // to the VFP2 class (D0-D15). We currently model this constraint prior to
1487 // coalescing by double-counting the SP regs. See the FIXME above.
1488 if (Subtarget->useNEONForSinglePrecisionFP())
1489 Cost = 2;
1490 break;
1491 case MVT::v16i8: case MVT::v8i16: case MVT::v4i32: case MVT::v2i64:
1492 case MVT::v4f32: case MVT::v2f64:
1493 RRC = &ARM::DPRRegClass;
1494 Cost = 2;
1495 break;
1496 case MVT::v4i64:
1497 RRC = &ARM::DPRRegClass;
1498 Cost = 4;
1499 break;
1500 case MVT::v8i64:
1501 RRC = &ARM::DPRRegClass;
1502 Cost = 8;
1503 break;
1504 }
1505 return std::make_pair(RRC, Cost);
1506}
1507
1509 EVT VT) const {
1510 if (!VT.isVector())
1511 return getPointerTy(DL);
1512
1513 // MVE has a predicate register.
1514 if (Subtarget->hasMVEIntegerOps())
1515 return EVT::getVectorVT(C, MVT::i1, VT.getVectorElementCount());
1516
1518}
1519
1520/// getRegClassFor - Return the register class that should be used for the
1521/// specified value type.
1522const TargetRegisterClass *
1523ARMTargetLowering::getRegClassFor(MVT VT, bool isDivergent) const {
1524 (void)isDivergent;
1525 // Map v4i64 to QQ registers but do not make the type legal. Similarly map
1526 // v8i64 to QQQQ registers. v4i64 and v8i64 are only used for REG_SEQUENCE to
1527 // load / store 4 to 8 consecutive NEON D registers, or 2 to 4 consecutive
1528 // MVE Q registers.
1529 if (Subtarget->hasNEON()) {
1530 if (VT == MVT::v4i64)
1531 return &ARM::QQPRRegClass;
1532 if (VT == MVT::v8i64)
1533 return &ARM::QQQQPRRegClass;
1534 }
1535 if (Subtarget->hasMVEIntegerOps()) {
1536 if (VT == MVT::v4i64)
1537 return &ARM::MQQPRRegClass;
1538 if (VT == MVT::v8i64)
1539 return &ARM::MQQQQPRRegClass;
1540 }
1542}
1543
1544// memcpy, and other memory intrinsics, typically tries to use LDM/STM if the
1545// source/dest is aligned and the copy size is large enough. We therefore want
1546// to align such objects passed to memory intrinsics.
1548 Align &PrefAlign) const {
1549 if (!isa<MemIntrinsic>(CI))
1550 return false;
1551 MinSize = 8;
1552 // On ARM11 onwards (excluding M class) 8-byte aligned LDM is typically 1
1553 // cycle faster than 4-byte aligned LDM.
1554 PrefAlign =
1555 (Subtarget->hasV6Ops() && !Subtarget->isMClass() ? Align(8) : Align(4));
1556 return true;
1557}
1558
1559// Create a fast isel object.
1561 FunctionLoweringInfo &funcInfo, const TargetLibraryInfo *libInfo,
1562 const LibcallLoweringInfo *libcallLowering) const {
1563 return ARM::createFastISel(funcInfo, libInfo, libcallLowering);
1564}
1565
1567 unsigned NumVals = N->getNumValues();
1568 if (!NumVals)
1569 return Sched::RegPressure;
1570
1571 for (unsigned i = 0; i != NumVals; ++i) {
1572 EVT VT = N->getValueType(i);
1573 if (VT == MVT::Glue || VT == MVT::Other)
1574 continue;
1575 if (VT.isFloatingPoint() || VT.isVector())
1576 return Sched::ILP;
1577 }
1578
1579 if (!N->isMachineOpcode())
1580 return Sched::RegPressure;
1581
1582 // Load are scheduled for latency even if there instruction itinerary
1583 // is not available.
1584 const TargetInstrInfo *TII = Subtarget->getInstrInfo();
1585 const MCInstrDesc &MCID = TII->get(N->getMachineOpcode());
1586
1587 if (MCID.getNumDefs() == 0)
1588 return Sched::RegPressure;
1589 if (!Itins->isEmpty() &&
1590 Itins->getOperandCycle(MCID.getSchedClass(), 0) > 2U)
1591 return Sched::ILP;
1592
1593 return Sched::RegPressure;
1594}
1595
1596//===----------------------------------------------------------------------===//
1597// Lowering Code
1598//===----------------------------------------------------------------------===//
1599
1600static bool isSRL16(const SDValue &Op) {
1601 if (Op.getOpcode() != ISD::SRL)
1602 return false;
1603 if (auto Const = dyn_cast<ConstantSDNode>(Op.getOperand(1)))
1604 return Const->getZExtValue() == 16;
1605 return false;
1606}
1607
1608static bool isSRA16(const SDValue &Op) {
1609 if (Op.getOpcode() != ISD::SRA)
1610 return false;
1611 if (auto Const = dyn_cast<ConstantSDNode>(Op.getOperand(1)))
1612 return Const->getZExtValue() == 16;
1613 return false;
1614}
1615
1616static bool isSHL16(const SDValue &Op) {
1617 if (Op.getOpcode() != ISD::SHL)
1618 return false;
1619 if (auto Const = dyn_cast<ConstantSDNode>(Op.getOperand(1)))
1620 return Const->getZExtValue() == 16;
1621 return false;
1622}
1623
1624// Check for a signed 16-bit value. We special case SRA because it makes it
1625// more simple when also looking for SRAs that aren't sign extending a
1626// smaller value. Without the check, we'd need to take extra care with
1627// checking order for some operations.
1628static bool isS16(const SDValue &Op, SelectionDAG &DAG) {
1629 if (isSRA16(Op))
1630 return isSHL16(Op.getOperand(0));
1631 return DAG.ComputeNumSignBits(Op) == 17;
1632}
1633
1634/// IntCCToARMCC - Convert a DAG integer condition code to an ARM CC
1636 switch (CC) {
1637 default: llvm_unreachable("Unknown condition code!");
1638 case ISD::SETNE: return ARMCC::NE;
1639 case ISD::SETEQ: return ARMCC::EQ;
1640 case ISD::SETGT: return ARMCC::GT;
1641 case ISD::SETGE: return ARMCC::GE;
1642 case ISD::SETLT: return ARMCC::LT;
1643 case ISD::SETLE: return ARMCC::LE;
1644 case ISD::SETUGT: return ARMCC::HI;
1645 case ISD::SETUGE: return ARMCC::HS;
1646 case ISD::SETULT: return ARMCC::LO;
1647 case ISD::SETULE: return ARMCC::LS;
1648 }
1649}
1650
1651/// FPCCToARMCC - Convert a DAG fp condition code to an ARM CC.
1653 ARMCC::CondCodes &CondCode2) {
1654 CondCode2 = ARMCC::AL;
1655 switch (CC) {
1656 default: llvm_unreachable("Unknown FP condition!");
1657 case ISD::SETEQ:
1658 case ISD::SETOEQ: CondCode = ARMCC::EQ; break;
1659 case ISD::SETGT:
1660 case ISD::SETOGT: CondCode = ARMCC::GT; break;
1661 case ISD::SETGE:
1662 case ISD::SETOGE: CondCode = ARMCC::GE; break;
1663 case ISD::SETOLT: CondCode = ARMCC::MI; break;
1664 case ISD::SETOLE: CondCode = ARMCC::LS; break;
1665 case ISD::SETONE: CondCode = ARMCC::MI; CondCode2 = ARMCC::GT; break;
1666 case ISD::SETO: CondCode = ARMCC::VC; break;
1667 case ISD::SETUO: CondCode = ARMCC::VS; break;
1668 case ISD::SETUEQ: CondCode = ARMCC::EQ; CondCode2 = ARMCC::VS; break;
1669 case ISD::SETUGT: CondCode = ARMCC::HI; break;
1670 case ISD::SETUGE: CondCode = ARMCC::PL; break;
1671 case ISD::SETLT:
1672 case ISD::SETULT: CondCode = ARMCC::LT; break;
1673 case ISD::SETLE:
1674 case ISD::SETULE: CondCode = ARMCC::LE; break;
1675 case ISD::SETNE:
1676 case ISD::SETUNE: CondCode = ARMCC::NE; break;
1677 }
1678}
1679
1680//===----------------------------------------------------------------------===//
1681// Calling Convention Implementation
1682//===----------------------------------------------------------------------===//
1683
1684/// getEffectiveCallingConv - Get the effective calling convention, taking into
1685/// account presence of floating point hardware and calling convention
1686/// limitations, such as support for variadic functions.
1689 bool isVarArg) const {
1690 switch (CC) {
1691 default:
1692 // Unknown CCs are rejected when calling convention lowering is required.
1695 case CallingConv::GHC:
1697 return CC;
1703 case CallingConv::Swift:
1706 case CallingConv::C:
1707 case CallingConv::Tail:
1708 if (!Subtarget->isAAPCS_ABI())
1709 return CallingConv::ARM_APCS;
1710 else if (Subtarget->isTargetHardFloat() && !isVarArg)
1712 else
1714 case CallingConv::Fast:
1716 if (!Subtarget->isAAPCS_ABI()) {
1717 if (Subtarget->hasFPRegs() && !Subtarget->isThumb1Only() && !isVarArg)
1718 return CallingConv::Fast;
1719 return CallingConv::ARM_APCS;
1720 } else if (Subtarget->hasFPRegs() && !Subtarget->isThumb1Only() &&
1721 !isVarArg)
1723 else
1725 }
1726}
1727
1729 bool isVarArg) const {
1730 return CCAssignFnForNode(CC, false, isVarArg);
1731}
1732
1734 bool isVarArg) const {
1735 return CCAssignFnForNode(CC, true, isVarArg);
1736}
1737
1738/// CCAssignFnForNode - Selects the correct CCAssignFn for the given
1739/// CallingConvention.
1740CCAssignFn *ARMTargetLowering::CCAssignFnForNode(CallingConv::ID CC,
1741 bool Return,
1742 bool isVarArg) const {
1743 switch (getEffectiveCallingConv(CC, isVarArg)) {
1744 default:
1745 report_fatal_error("Unsupported calling convention");
1747 return (Return ? RetCC_ARM_APCS : CC_ARM_APCS);
1749 return (Return ? RetCC_ARM_AAPCS : CC_ARM_AAPCS);
1751 return (Return ? RetCC_ARM_AAPCS_VFP : CC_ARM_AAPCS_VFP);
1752 case CallingConv::Fast:
1753 return (Return ? RetFastCC_ARM_APCS : FastCC_ARM_APCS);
1754 case CallingConv::GHC:
1755 return (Return ? RetCC_ARM_APCS : CC_ARM_APCS_GHC);
1757 return (Return ? RetCC_ARM_AAPCS : CC_ARM_AAPCS);
1759 return (Return ? RetCC_ARM_AAPCS : CC_ARM_AAPCS);
1761 return (Return ? RetCC_ARM_AAPCS : CC_ARM_Win32_CFGuard_Check);
1762 }
1763}
1764
1765SDValue ARMTargetLowering::MoveToHPR(const SDLoc &dl, SelectionDAG &DAG,
1766 MVT LocVT, MVT ValVT, SDValue Val) const {
1767 Val = DAG.getNode(ISD::BITCAST, dl, MVT::getIntegerVT(LocVT.getSizeInBits()),
1768 Val);
1769 if (Subtarget->hasFullFP16()) {
1770 Val = DAG.getNode(ARMISD::VMOVhr, dl, ValVT, Val);
1771 } else {
1772 Val = DAG.getNode(ISD::TRUNCATE, dl,
1773 MVT::getIntegerVT(ValVT.getSizeInBits()), Val);
1774 Val = DAG.getNode(ISD::BITCAST, dl, ValVT, Val);
1775 }
1776 return Val;
1777}
1778
1779SDValue ARMTargetLowering::MoveFromHPR(const SDLoc &dl, SelectionDAG &DAG,
1780 MVT LocVT, MVT ValVT,
1781 SDValue Val) const {
1782 if (Subtarget->hasFullFP16()) {
1783 Val = DAG.getNode(ARMISD::VMOVrh, dl,
1784 MVT::getIntegerVT(LocVT.getSizeInBits()), Val);
1785 } else {
1786 Val = DAG.getNode(ISD::BITCAST, dl,
1787 MVT::getIntegerVT(ValVT.getSizeInBits()), Val);
1788 Val = DAG.getNode(ISD::ZERO_EXTEND, dl,
1789 MVT::getIntegerVT(LocVT.getSizeInBits()), Val);
1790 }
1791 return DAG.getNode(ISD::BITCAST, dl, LocVT, Val);
1792}
1793
1794/// LowerCallResult - Lower the result values of a call into the
1795/// appropriate copies out of appropriate physical registers.
1796SDValue ARMTargetLowering::LowerCallResult(
1797 SDValue Chain, SDValue InGlue, CallingConv::ID CallConv, bool isVarArg,
1798 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
1799 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals, bool isThisReturn,
1800 SDValue ThisVal, bool isCmseNSCall) const {
1801 // Assign locations to each value returned by this call.
1803 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), RVLocs,
1804 *DAG.getContext());
1805 CCInfo.AnalyzeCallResult(Ins, CCAssignFnForReturn(CallConv, isVarArg));
1806
1807 // Copy all of the result registers out of their specified physreg.
1808 for (unsigned i = 0; i != RVLocs.size(); ++i) {
1809 CCValAssign VA = RVLocs[i];
1810
1811 // Pass 'this' value directly from the argument to return value, to avoid
1812 // reg unit interference
1813 if (i == 0 && isThisReturn) {
1814 assert(!VA.needsCustom() && VA.getLocVT() == MVT::i32 &&
1815 "unexpected return calling convention register assignment");
1816 InVals.push_back(ThisVal);
1817 continue;
1818 }
1819
1820 SDValue Val;
1821 if (VA.needsCustom() &&
1822 (VA.getLocVT() == MVT::f64 || VA.getLocVT() == MVT::v2f64)) {
1823 // Handle f64 or half of a v2f64.
1824 SDValue Lo = DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), MVT::i32,
1825 InGlue);
1826 Chain = Lo.getValue(1);
1827 InGlue = Lo.getValue(2);
1828 VA = RVLocs[++i]; // skip ahead to next loc
1829 SDValue Hi = DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), MVT::i32,
1830 InGlue);
1831 Chain = Hi.getValue(1);
1832 InGlue = Hi.getValue(2);
1833 if (!Subtarget->isLittle())
1834 std::swap (Lo, Hi);
1835 Val = DAG.getNode(ARMISD::VMOVDRR, dl, MVT::f64, Lo, Hi);
1836
1837 if (VA.getLocVT() == MVT::v2f64) {
1838 SDValue Vec = DAG.getNode(ISD::UNDEF, dl, MVT::v2f64);
1839 Vec = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, MVT::v2f64, Vec, Val,
1840 DAG.getConstant(0, dl, MVT::i32));
1841
1842 VA = RVLocs[++i]; // skip ahead to next loc
1843 Lo = DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), MVT::i32, InGlue);
1844 Chain = Lo.getValue(1);
1845 InGlue = Lo.getValue(2);
1846 VA = RVLocs[++i]; // skip ahead to next loc
1847 Hi = DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), MVT::i32, InGlue);
1848 Chain = Hi.getValue(1);
1849 InGlue = Hi.getValue(2);
1850 if (!Subtarget->isLittle())
1851 std::swap (Lo, Hi);
1852 Val = DAG.getNode(ARMISD::VMOVDRR, dl, MVT::f64, Lo, Hi);
1853 Val = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, MVT::v2f64, Vec, Val,
1854 DAG.getConstant(1, dl, MVT::i32));
1855 }
1856 } else {
1857 Val = DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), VA.getLocVT(),
1858 InGlue);
1859 Chain = Val.getValue(1);
1860 InGlue = Val.getValue(2);
1861 }
1862
1863 switch (VA.getLocInfo()) {
1864 default: llvm_unreachable("Unknown loc info!");
1865 case CCValAssign::Full: break;
1866 case CCValAssign::BCvt:
1867 Val = DAG.getNode(ISD::BITCAST, dl, VA.getValVT(), Val);
1868 break;
1869 }
1870
1871 // f16 arguments have their size extended to 4 bytes and passed as if they
1872 // had been copied to the LSBs of a 32-bit register.
1873 // For that, it's passed extended to i32 (soft ABI) or to f32 (hard ABI)
1874 if (VA.needsCustom() &&
1875 (VA.getValVT() == MVT::f16 || VA.getValVT() == MVT::bf16))
1876 Val = MoveToHPR(dl, DAG, VA.getLocVT(), VA.getValVT(), Val);
1877
1878 // On CMSE Non-secure Calls, call results (returned values) whose bitwidth
1879 // is less than 32 bits must be sign- or zero-extended after the call for
1880 // security reasons. Although the ABI mandates an extension done by the
1881 // callee, the latter cannot be trusted to follow the rules of the ABI.
1882 const ISD::InputArg &Arg = Ins[VA.getValNo()];
1883 if (isCmseNSCall && Arg.ArgVT.isScalarInteger() &&
1884 VA.getLocVT().isScalarInteger() && Arg.ArgVT.bitsLT(MVT::i32))
1885 Val = handleCMSEValue(Val, Arg, DAG, dl);
1886
1887 InVals.push_back(Val);
1888 }
1889
1890 return Chain;
1891}
1892
1893std::pair<SDValue, MachinePointerInfo> ARMTargetLowering::computeAddrForCallArg(
1894 const SDLoc &dl, SelectionDAG &DAG, const CCValAssign &VA, SDValue StackPtr,
1895 bool IsTailCall, int SPDiff) const {
1896 SDValue DstAddr;
1897 MachinePointerInfo DstInfo;
1898 int32_t Offset = VA.getLocMemOffset();
1900
1901 if (IsTailCall) {
1902 Offset += SPDiff;
1903 auto PtrVT = getPointerTy(DAG.getDataLayout());
1904 int Size = VA.getLocVT().getFixedSizeInBits() / 8;
1905 int FI = MF.getFrameInfo().CreateFixedObject(Size, Offset, true);
1906 DstAddr = DAG.getFrameIndex(FI, PtrVT);
1907 DstInfo =
1909 } else {
1910 SDValue PtrOff = DAG.getIntPtrConstant(Offset, dl);
1911 DstAddr = DAG.getNode(ISD::ADD, dl, getPointerTy(DAG.getDataLayout()),
1912 StackPtr, PtrOff);
1913 DstInfo =
1915 }
1916
1917 return std::make_pair(DstAddr, DstInfo);
1918}
1919
1920// Returns the type of copying which is required to set up a byval argument to
1921// a tail-called function. This isn't needed for non-tail calls, because they
1922// always need the equivalent of CopyOnce, but tail-calls sometimes need two to
1923// avoid clobbering another argument (CopyViaTemp), and sometimes can be
1924// optimised to zero copies when forwarding an argument from the caller's
1925// caller (NoCopy).
1926ARMTargetLowering::ByValCopyKind ARMTargetLowering::ByValNeedsCopyForTailCall(
1927 SelectionDAG &DAG, SDValue Src, SDValue Dst, ISD::ArgFlagsTy Flags) const {
1928 MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();
1929 ARMFunctionInfo *AFI = DAG.getMachineFunction().getInfo<ARMFunctionInfo>();
1930
1931 // Globals are always safe to copy from.
1933 return CopyOnce;
1934
1935 // Can only analyse frame index nodes, conservatively assume we need a
1936 // temporary.
1937 auto *SrcFrameIdxNode = dyn_cast<FrameIndexSDNode>(Src);
1938 auto *DstFrameIdxNode = dyn_cast<FrameIndexSDNode>(Dst);
1939 if (!SrcFrameIdxNode || !DstFrameIdxNode)
1940 return CopyViaTemp;
1941
1942 int SrcFI = SrcFrameIdxNode->getIndex();
1943 int DstFI = DstFrameIdxNode->getIndex();
1944 assert(MFI.isFixedObjectIndex(DstFI) &&
1945 "byval passed in non-fixed stack slot");
1946
1947 int64_t SrcOffset = MFI.getObjectOffset(SrcFI);
1948 int64_t DstOffset = MFI.getObjectOffset(DstFI);
1949
1950 // If the source is in the local frame, then the copy to the argument memory
1951 // is always valid.
1952 bool FixedSrc = MFI.isFixedObjectIndex(SrcFI);
1953 if (!FixedSrc ||
1954 (FixedSrc && SrcOffset < -(int64_t)AFI->getArgRegsSaveSize()))
1955 return CopyOnce;
1956
1957 // In the case of byval arguments split between registers and the stack,
1958 // computeAddrForCallArg returns a FrameIndex which corresponds only to the
1959 // stack portion, but the Src SDValue will refer to the full value, including
1960 // the local stack memory that the register portion gets stored into. We only
1961 // need to compare them for equality, so normalise on the full value version.
1962 uint64_t RegSize = Flags.getByValSize() - MFI.getObjectSize(DstFI);
1963 DstOffset -= RegSize;
1964
1965 // If the value is already in the correct location, then no copying is
1966 // needed. If not, then we need to copy via a temporary.
1967 if (SrcOffset == DstOffset)
1968 return NoCopy;
1969 else
1970 return CopyViaTemp;
1971}
1972
1973void ARMTargetLowering::PassF64ArgInRegs(const SDLoc &dl, SelectionDAG &DAG,
1974 SDValue Chain, SDValue &Arg,
1975 RegsToPassVector &RegsToPass,
1976 CCValAssign &VA, CCValAssign &NextVA,
1977 SDValue &StackPtr,
1978 SmallVectorImpl<SDValue> &MemOpChains,
1979 bool IsTailCall,
1980 int SPDiff) const {
1981 SDValue fmrrd = DAG.getNode(ARMISD::VMOVRRD, dl,
1982 DAG.getVTList(MVT::i32, MVT::i32), Arg);
1983 unsigned id = Subtarget->isLittle() ? 0 : 1;
1984 RegsToPass.push_back(std::make_pair(VA.getLocReg(), fmrrd.getValue(id)));
1985
1986 if (NextVA.isRegLoc())
1987 RegsToPass.push_back(std::make_pair(NextVA.getLocReg(), fmrrd.getValue(1-id)));
1988 else {
1989 assert(NextVA.isMemLoc());
1990 if (!StackPtr.getNode())
1991 StackPtr = DAG.getCopyFromReg(Chain, dl, ARM::SP,
1993
1994 SDValue DstAddr;
1995 MachinePointerInfo DstInfo;
1996 std::tie(DstAddr, DstInfo) =
1997 computeAddrForCallArg(dl, DAG, NextVA, StackPtr, IsTailCall, SPDiff);
1998 MemOpChains.push_back(
1999 DAG.getStore(Chain, dl, fmrrd.getValue(1 - id), DstAddr, DstInfo));
2000 }
2001}
2002
2003static bool canGuaranteeTCO(CallingConv::ID CC, bool GuaranteeTailCalls) {
2004 return (CC == CallingConv::Fast && GuaranteeTailCalls) ||
2006}
2007
2008/// LowerCall - Lowering a call into a callseq_start <-
2009/// ARMISD:CALL <- callseq_end chain. Also add input and output parameter
2010/// nodes.
2011SDValue
2012ARMTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
2013 SmallVectorImpl<SDValue> &InVals) const {
2014 SelectionDAG &DAG = CLI.DAG;
2015 SDLoc &dl = CLI.DL;
2016 SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
2017 SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
2018 SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins;
2019 SDValue Chain = CLI.Chain;
2020 SDValue Callee = CLI.Callee;
2021 bool &isTailCall = CLI.IsTailCall;
2022 CallingConv::ID CallConv = CLI.CallConv;
2023 bool doesNotRet = CLI.DoesNotReturn;
2024 bool isVarArg = CLI.IsVarArg;
2025 const CallBase *CB = CLI.CB;
2026
2028 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
2029 MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();
2030 MachineFunction::CallSiteInfo CSInfo;
2031 bool isStructRet = (Outs.empty()) ? false : Outs[0].Flags.isSRet();
2032 bool isThisReturn = false;
2033 bool isCmseNSCall = false;
2034 bool isSibCall = false;
2035 bool PreferIndirect = false;
2036 bool GuardWithBTI = false;
2037
2038 // Analyze operands of the call, assigning locations to each operand.
2040 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), ArgLocs,
2041 *DAG.getContext());
2042 CCInfo.AnalyzeCallOperands(Outs, CCAssignFnForCall(CallConv, isVarArg));
2043
2044 // Lower 'returns_twice' calls to a pseudo-instruction.
2045 if (CLI.CB && CLI.CB->getAttributes().hasFnAttr(Attribute::ReturnsTwice) &&
2046 !Subtarget->noBTIAtReturnTwice())
2047 GuardWithBTI = AFI->branchTargetEnforcement();
2048
2049 // Set type id for call site info.
2050 setTypeIdForCallsiteInfo(CB, MF, CSInfo);
2051
2052 // Determine whether this is a non-secure function call.
2053 if (CLI.CB && CLI.CB->getAttributes().hasFnAttr("cmse_nonsecure_call"))
2054 isCmseNSCall = true;
2055
2056 // Disable tail calls if they're not supported.
2057 if (!Subtarget->supportsTailCall())
2058 isTailCall = false;
2059
2060 // For both the non-secure calls and the returns from a CMSE entry function,
2061 // the function needs to do some extra work after the call, or before the
2062 // return, respectively, thus it cannot end with a tail call
2063 if (isCmseNSCall || AFI->isCmseNSEntryFunction())
2064 isTailCall = false;
2065
2066 if (isa<GlobalAddressSDNode>(Callee)) {
2067 // If we're optimizing for minimum size and the function is called three or
2068 // more times in this block, we can improve codesize by calling indirectly
2069 // as BLXr has a 16-bit encoding.
2070 auto *GV = cast<GlobalAddressSDNode>(Callee)->getGlobal();
2071 if (CLI.CB) {
2072 auto *BB = CLI.CB->getParent();
2073 PreferIndirect = Subtarget->isThumb() && Subtarget->hasMinSize() &&
2074 count_if(GV->users(), [&BB](const User *U) {
2075 return isa<Instruction>(U) &&
2076 cast<Instruction>(U)->getParent() == BB;
2077 }) > 2;
2078 }
2079 }
2080 if (isTailCall) {
2081 // Check if it's really possible to do a tail call.
2082 isTailCall =
2083 IsEligibleForTailCallOptimization(CLI, CCInfo, ArgLocs, PreferIndirect);
2084
2085 if (isTailCall && !getTargetMachine().Options.GuaranteedTailCallOpt &&
2086 CallConv != CallingConv::Tail && CallConv != CallingConv::SwiftTail)
2087 isSibCall = true;
2088
2089 // We don't support GuaranteedTailCallOpt for ARM, only automatically
2090 // detected sibcalls.
2091 if (isTailCall)
2092 ++NumTailCalls;
2093 }
2094
2095 if (!isTailCall && CLI.CB && CLI.CB->isMustTailCall())
2096 report_fatal_error("failed to perform tail call elimination on a call "
2097 "site marked musttail");
2098
2099 // Get a count of how many bytes are to be pushed on the stack.
2100 unsigned NumBytes = CCInfo.getStackSize();
2101
2102 // SPDiff is the byte offset of the call's argument area from the callee's.
2103 // Stores to callee stack arguments will be placed in FixedStackSlots offset
2104 // by this amount for a tail call. In a sibling call it must be 0 because the
2105 // caller will deallocate the entire stack and the callee still expects its
2106 // arguments to begin at SP+0. Completely unused for non-tail calls.
2107 int SPDiff = 0;
2108
2109 if (isTailCall && !isSibCall) {
2110 auto FuncInfo = MF.getInfo<ARMFunctionInfo>();
2111 unsigned NumReusableBytes = FuncInfo->getArgumentStackSize();
2112
2113 // Since callee will pop argument stack as a tail call, we must keep the
2114 // popped size 16-byte aligned.
2115 MaybeAlign StackAlign = DAG.getDataLayout().getStackAlignment();
2116 assert(StackAlign && "data layout string is missing stack alignment");
2117 NumBytes = alignTo(NumBytes, *StackAlign);
2118
2119 // SPDiff will be negative if this tail call requires more space than we
2120 // would automatically have in our incoming argument space. Positive if we
2121 // can actually shrink the stack.
2122 SPDiff = NumReusableBytes - NumBytes;
2123
2124 // If this call requires more stack than we have available from
2125 // LowerFormalArguments, tell FrameLowering to reserve space for it.
2126 if (SPDiff < 0 && AFI->getArgRegsSaveSize() < (unsigned)-SPDiff)
2127 AFI->setArgRegsSaveSize(-SPDiff);
2128 }
2129
2130 if (isSibCall) {
2131 // For sibling tail calls, memory operands are available in our caller's stack.
2132 NumBytes = 0;
2133 } else {
2134 // Adjust the stack pointer for the new arguments...
2135 // These operations are automatically eliminated by the prolog/epilog pass
2136 Chain = DAG.getCALLSEQ_START(Chain, isTailCall ? 0 : NumBytes, 0, dl);
2137 }
2138
2139 SDValue StackPtr =
2140 DAG.getCopyFromReg(Chain, dl, ARM::SP, getPointerTy(DAG.getDataLayout()));
2141
2142 RegsToPassVector RegsToPass;
2143 SmallVector<SDValue, 8> MemOpChains;
2144
2145 // If we are doing a tail-call, any byval arguments will be written to stack
2146 // space which was used for incoming arguments. If any the values being used
2147 // are incoming byval arguments to this function, then they might be
2148 // overwritten by the stores of the outgoing arguments. To avoid this, we
2149 // need to make a temporary copy of them in local stack space, then copy back
2150 // to the argument area.
2151 DenseMap<unsigned, SDValue> ByValTemporaries;
2152 SDValue ByValTempChain;
2153 if (isTailCall) {
2154 SmallVector<SDValue, 8> ByValCopyChains;
2155 for (const CCValAssign &VA : ArgLocs) {
2156 unsigned ArgIdx = VA.getValNo();
2157 SDValue Src = OutVals[ArgIdx];
2158 ISD::ArgFlagsTy Flags = Outs[ArgIdx].Flags;
2159
2160 if (!Flags.isByVal())
2161 continue;
2162
2163 SDValue Dst;
2164 MachinePointerInfo DstInfo;
2165 std::tie(Dst, DstInfo) =
2166 computeAddrForCallArg(dl, DAG, VA, SDValue(), true, SPDiff);
2167 ByValCopyKind Copy = ByValNeedsCopyForTailCall(DAG, Src, Dst, Flags);
2168
2169 if (Copy == NoCopy) {
2170 // If the argument is already at the correct offset on the stack
2171 // (because we are forwarding a byval argument from our caller), we
2172 // don't need any copying.
2173 continue;
2174 } else if (Copy == CopyOnce) {
2175 // If the argument is in our local stack frame, no other argument
2176 // preparation can clobber it, so we can copy it to the final location
2177 // later.
2178 ByValTemporaries[ArgIdx] = Src;
2179 } else {
2180 assert(Copy == CopyViaTemp && "unexpected enum value");
2181 // If we might be copying this argument from the outgoing argument
2182 // stack area, we need to copy via a temporary in the local stack
2183 // frame.
2184 int TempFrameIdx = MFI.CreateStackObject(
2185 Flags.getByValSize(), Flags.getNonZeroByValAlign(), false);
2186 SDValue Temp =
2187 DAG.getFrameIndex(TempFrameIdx, getPointerTy(DAG.getDataLayout()));
2188
2189 SDValue SizeNode = DAG.getConstant(Flags.getByValSize(), dl, MVT::i32);
2190 SDValue AlignNode =
2191 DAG.getConstant(Flags.getNonZeroByValAlign().value(), dl, MVT::i32);
2192
2193 SDVTList VTs = DAG.getVTList(MVT::Other, MVT::Glue);
2194 SDValue Ops[] = {Chain, Temp, Src, SizeNode, AlignNode};
2195 ByValCopyChains.push_back(
2196 DAG.getNode(ARMISD::COPY_STRUCT_BYVAL, dl, VTs, Ops));
2197 ByValTemporaries[ArgIdx] = Temp;
2198 }
2199 }
2200 if (!ByValCopyChains.empty())
2201 ByValTempChain =
2202 DAG.getNode(ISD::TokenFactor, dl, MVT::Other, ByValCopyChains);
2203 }
2204
2205 // During a tail call, stores to the argument area must happen after all of
2206 // the function's incoming arguments have been loaded because they may alias.
2207 // This is done by folding in a TokenFactor from LowerFormalArguments, but
2208 // there's no point in doing so repeatedly so this tracks whether that's
2209 // happened yet.
2210 bool AfterFormalArgLoads = false;
2211
2212 // Walk the register/memloc assignments, inserting copies/loads. In the case
2213 // of tail call optimization, arguments are handled later.
2214 for (unsigned i = 0, realArgIdx = 0, e = ArgLocs.size();
2215 i != e;
2216 ++i, ++realArgIdx) {
2217 CCValAssign &VA = ArgLocs[i];
2218 SDValue Arg = OutVals[realArgIdx];
2219 ISD::ArgFlagsTy Flags = Outs[realArgIdx].Flags;
2220 bool isByVal = Flags.isByVal();
2221
2222 // Promote the value if needed.
2223 switch (VA.getLocInfo()) {
2224 default: llvm_unreachable("Unknown loc info!");
2225 case CCValAssign::Full: break;
2226 case CCValAssign::SExt:
2227 Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg);
2228 break;
2229 case CCValAssign::ZExt:
2230 Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg);
2231 break;
2232 case CCValAssign::AExt:
2233 Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg);
2234 break;
2235 case CCValAssign::BCvt:
2236 Arg = DAG.getNode(ISD::BITCAST, dl, VA.getLocVT(), Arg);
2237 break;
2238 }
2239
2240 if (isTailCall && VA.isMemLoc() && !AfterFormalArgLoads) {
2241 Chain = DAG.getStackArgumentTokenFactor(Chain);
2242 if (ByValTempChain) {
2243 // In case of large byval copies, re-using the stackframe for tail-calls
2244 // can lead to overwriting incoming arguments on the stack. Force
2245 // loading these stack arguments before the copy to avoid that.
2246 SmallVector<SDValue, 8> IncomingLoad;
2247 for (unsigned I = 0; I < OutVals.size(); ++I) {
2248 if (Outs[I].Flags.isByVal())
2249 continue;
2250
2251 SDValue OutVal = OutVals[I];
2252 LoadSDNode *OutLN = dyn_cast_or_null<LoadSDNode>(OutVal);
2253 if (!OutLN)
2254 continue;
2255
2256 FrameIndexSDNode *FIN =
2258 if (!FIN)
2259 continue;
2260
2261 if (!MFI.isFixedObjectIndex(FIN->getIndex()))
2262 continue;
2263
2264 for (const CCValAssign &VA : ArgLocs) {
2265 if (VA.isMemLoc())
2266 IncomingLoad.push_back(OutVal.getValue(1));
2267 }
2268 }
2269
2270 // Update the chain to force loads for potentially clobbered argument
2271 // loads to happen before the byval copy.
2272 if (!IncomingLoad.empty()) {
2273 IncomingLoad.push_back(Chain);
2274 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, IncomingLoad);
2275 }
2276
2277 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Chain,
2278 ByValTempChain);
2279 }
2280 AfterFormalArgLoads = true;
2281 }
2282
2283 // f16 arguments have their size extended to 4 bytes and passed as if they
2284 // had been copied to the LSBs of a 32-bit register.
2285 // For that, it's passed extended to i32 (soft ABI) or to f32 (hard ABI)
2286 if (VA.needsCustom() &&
2287 (VA.getValVT() == MVT::f16 || VA.getValVT() == MVT::bf16)) {
2288 Arg = MoveFromHPR(dl, DAG, VA.getLocVT(), VA.getValVT(), Arg);
2289 } else {
2290 // f16 arguments could have been extended prior to argument lowering.
2291 // Mask them arguments if this is a CMSE nonsecure call.
2292 auto ArgVT = Outs[realArgIdx].ArgVT;
2293 if (isCmseNSCall && (ArgVT == MVT::f16)) {
2294 auto LocBits = VA.getLocVT().getSizeInBits();
2295 auto MaskValue = APInt::getLowBitsSet(LocBits, ArgVT.getSizeInBits());
2296 SDValue Mask =
2297 DAG.getConstant(MaskValue, dl, MVT::getIntegerVT(LocBits));
2298 Arg = DAG.getNode(ISD::BITCAST, dl, MVT::getIntegerVT(LocBits), Arg);
2299 Arg = DAG.getNode(ISD::AND, dl, MVT::getIntegerVT(LocBits), Arg, Mask);
2300 Arg = DAG.getNode(ISD::BITCAST, dl, VA.getLocVT(), Arg);
2301 }
2302 }
2303
2304 // f64 and v2f64 might be passed in i32 pairs and must be split into pieces
2305 if (VA.needsCustom() && VA.getLocVT() == MVT::v2f64) {
2306 SDValue Op0 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f64, Arg,
2307 DAG.getConstant(0, dl, MVT::i32));
2308 SDValue Op1 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f64, Arg,
2309 DAG.getConstant(1, dl, MVT::i32));
2310
2311 PassF64ArgInRegs(dl, DAG, Chain, Op0, RegsToPass, VA, ArgLocs[++i],
2312 StackPtr, MemOpChains, isTailCall, SPDiff);
2313
2314 VA = ArgLocs[++i]; // skip ahead to next loc
2315 if (VA.isRegLoc()) {
2316 PassF64ArgInRegs(dl, DAG, Chain, Op1, RegsToPass, VA, ArgLocs[++i],
2317 StackPtr, MemOpChains, isTailCall, SPDiff);
2318 } else {
2319 assert(VA.isMemLoc());
2320 SDValue DstAddr;
2321 MachinePointerInfo DstInfo;
2322 std::tie(DstAddr, DstInfo) =
2323 computeAddrForCallArg(dl, DAG, VA, StackPtr, isTailCall, SPDiff);
2324 MemOpChains.push_back(DAG.getStore(Chain, dl, Op1, DstAddr, DstInfo));
2325 }
2326 } else if (VA.needsCustom() && VA.getLocVT() == MVT::f64) {
2327 PassF64ArgInRegs(dl, DAG, Chain, Arg, RegsToPass, VA, ArgLocs[++i],
2328 StackPtr, MemOpChains, isTailCall, SPDiff);
2329 } else if (VA.isRegLoc()) {
2330 if (realArgIdx == 0 && Flags.isReturned() && !Flags.isSwiftSelf() &&
2331 Outs[0].VT == MVT::i32) {
2332 assert(VA.getLocVT() == MVT::i32 &&
2333 "unexpected calling convention register assignment");
2334 assert(!Ins.empty() && Ins[0].VT == MVT::i32 &&
2335 "unexpected use of 'returned'");
2336 isThisReturn = true;
2337 }
2338 const TargetOptions &Options = DAG.getTarget().Options;
2339 if (Options.EmitCallSiteInfo)
2340 CSInfo.ArgRegPairs.emplace_back(VA.getLocReg(), i);
2341 RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
2342 } else if (isByVal) {
2343 assert(VA.isMemLoc());
2344 unsigned offset = 0;
2345
2346 // True if this byval aggregate will be split between registers
2347 // and memory.
2348 unsigned ByValArgsCount = CCInfo.getInRegsParamsCount();
2349 unsigned CurByValIdx = CCInfo.getInRegsParamsProcessed();
2350
2351 SDValue ByValSrc;
2352 bool NeedsStackCopy;
2353 if (auto It = ByValTemporaries.find(realArgIdx);
2354 It != ByValTemporaries.end()) {
2355 ByValSrc = It->second;
2356 NeedsStackCopy = true;
2357 } else {
2358 ByValSrc = Arg;
2359 NeedsStackCopy = !isTailCall;
2360 }
2361
2362 // If part of the argument is in registers, load them.
2363 if (CurByValIdx < ByValArgsCount) {
2364 unsigned RegBegin, RegEnd;
2365 CCInfo.getInRegsParamInfo(CurByValIdx, RegBegin, RegEnd);
2366
2367 EVT PtrVT = getPointerTy(DAG.getDataLayout());
2368 unsigned int i, j;
2369 for (i = 0, j = RegBegin; j < RegEnd; i++, j++) {
2370 SDValue Const = DAG.getConstant(4*i, dl, MVT::i32);
2371 SDValue AddArg = DAG.getNode(ISD::ADD, dl, PtrVT, ByValSrc, Const);
2372 SDValue Load =
2373 DAG.getLoad(PtrVT, dl, Chain, AddArg, MachinePointerInfo(),
2374 DAG.InferPtrAlign(AddArg));
2375 MemOpChains.push_back(Load.getValue(1));
2376 RegsToPass.push_back(std::make_pair(j, Load));
2377 }
2378
2379 // If parameter size outsides register area, "offset" value
2380 // helps us to calculate stack slot for remained part properly.
2381 offset = RegEnd - RegBegin;
2382
2383 CCInfo.nextInRegsParam();
2384 }
2385
2386 // If the memory part of the argument isn't already in the correct place
2387 // (which can happen with tail calls), copy it into the argument area.
2388 if (NeedsStackCopy && Flags.getByValSize() > 4 * offset) {
2389 auto PtrVT = getPointerTy(DAG.getDataLayout());
2390 SDValue Dst;
2391 MachinePointerInfo DstInfo;
2392 std::tie(Dst, DstInfo) =
2393 computeAddrForCallArg(dl, DAG, VA, StackPtr, isTailCall, SPDiff);
2394 SDValue SrcOffset = DAG.getIntPtrConstant(4*offset, dl);
2395 SDValue Src = DAG.getNode(ISD::ADD, dl, PtrVT, ByValSrc, SrcOffset);
2396 SDValue SizeNode = DAG.getConstant(Flags.getByValSize() - 4*offset, dl,
2397 MVT::i32);
2398 SDValue AlignNode =
2399 DAG.getConstant(Flags.getNonZeroByValAlign().value(), dl, MVT::i32);
2400
2401 SDVTList VTs = DAG.getVTList(MVT::Other, MVT::Glue);
2402 SDValue Ops[] = { Chain, Dst, Src, SizeNode, AlignNode};
2403 MemOpChains.push_back(DAG.getNode(ARMISD::COPY_STRUCT_BYVAL, dl, VTs,
2404 Ops));
2405 }
2406 } else {
2407 assert(VA.isMemLoc());
2408 SDValue DstAddr;
2409 MachinePointerInfo DstInfo;
2410 std::tie(DstAddr, DstInfo) =
2411 computeAddrForCallArg(dl, DAG, VA, StackPtr, isTailCall, SPDiff);
2412
2413 SDValue Store = DAG.getStore(Chain, dl, Arg, DstAddr, DstInfo);
2414 MemOpChains.push_back(Store);
2415 }
2416 }
2417
2418 if (!MemOpChains.empty())
2419 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOpChains);
2420
2421 // Build a sequence of copy-to-reg nodes chained together with token chain
2422 // and flag operands which copy the outgoing args into the appropriate regs.
2423 SDValue InGlue;
2424 for (const auto &[Reg, N] : RegsToPass) {
2425 Chain = DAG.getCopyToReg(Chain, dl, Reg, N, InGlue);
2426 InGlue = Chain.getValue(1);
2427 }
2428
2429 // If the callee is a GlobalAddress/ExternalSymbol node (quite common, every
2430 // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol
2431 // node so that legalize doesn't hack it.
2432 bool isDirect = false;
2433
2434 const TargetMachine &TM = getTargetMachine();
2435 const Triple &TT = TM.getTargetTriple();
2436 const GlobalValue *GVal = nullptr;
2437 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
2438 GVal = G->getGlobal();
2439 bool isStub = !TM.shouldAssumeDSOLocal(GVal) && TT.isOSBinFormatMachO();
2440
2441 bool isARMFunc = !Subtarget->isThumb() || (isStub && !Subtarget->isMClass());
2442 bool isLocalARMFunc = false;
2443 auto PtrVt = getPointerTy(DAG.getDataLayout());
2444
2445 if (Subtarget->genLongCalls()) {
2446 bool isPIC = isPositionIndependent() && !TT.isOSWindows();
2447 if (isPIC && Subtarget->genExecuteOnly())
2448 reportFatalUsageError("long-calls with execute-only and "
2449 "position-independent code is not supported");
2450 if (Subtarget->isROPI())
2451 reportFatalUsageError("long-calls with ROPI is not currently supported");
2452
2453 // Handle a global address or an external symbol. If it's not one of
2454 // those, the target's already in a register, so we don't need to do
2455 // anything extra.
2456 if (isa<GlobalAddressSDNode>(Callee)) {
2457 if (Subtarget->genExecuteOnly()) {
2458 // Execute-only forbids constant pools in .text, so use movw/movt.
2459 // fPIC is not supported with execute-only.
2460 if (Subtarget->useMovt())
2461 ++NumMovwMovt;
2462 Callee = DAG.getNode(ARMISD::Wrapper, dl, PtrVt,
2463 DAG.getTargetGlobalAddress(GVal, dl, PtrVt));
2464 } else if (isPIC) {
2465 // PIC without execute-only: use GOT-based addressing.
2466 // DSO-local symbols use a plain PC-relative WrapperPIC;
2467 // non-DSO-local symbols additionally load the address from the GOT.
2468 SDValue G = DAG.getTargetGlobalAddress(
2469 GVal, dl, PtrVt, 0, GVal->isDSOLocal() ? 0 : ARMII::MO_GOT);
2470 Callee = DAG.getNode(ARMISD::WrapperPIC, dl, PtrVt, G);
2471 if (!GVal->isDSOLocal())
2472 Callee =
2473 DAG.getLoad(PtrVt, dl, DAG.getEntryNode(), Callee,
2475 } else {
2476 // Neither execute-only nor PIC: load the address from a constant pool.
2477 unsigned ARMPCLabelIndex = AFI->createPICLabelUId();
2478 ARMConstantPoolValue *CPV = ARMConstantPoolConstant::Create(
2479 GVal, ARMPCLabelIndex, ARMCP::CPValue, 0);
2480
2481 // Get the address of the callee into a register
2482 SDValue Addr = DAG.getTargetConstantPool(CPV, PtrVt, Align(4));
2483 Addr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Addr);
2484 Callee = DAG.getLoad(
2485 PtrVt, dl, DAG.getEntryNode(), Addr,
2487 }
2488 } else if (ExternalSymbolSDNode *S=dyn_cast<ExternalSymbolSDNode>(Callee)) {
2489 const char *Sym = S->getSymbol();
2490
2491 if (Subtarget->genExecuteOnly()) {
2492 // Execute-only forbids constant pools in .text, so use movw/movt.
2493 // fPIC is not supported with execute-only.
2494 if (Subtarget->useMovt())
2495 ++NumMovwMovt;
2496 Callee = DAG.getNode(ARMISD::Wrapper, dl, PtrVt,
2497 DAG.getTargetExternalSymbol(Sym, PtrVt, 0));
2498 } else if (isPIC) {
2499 // PIC without execute-only: load the symbol's address from the GOT via
2500 // a GOT_PREL constant pool entry consumed by a PICLDR.
2501 unsigned PCAdj = Subtarget->isThumb() ? 4 : 8;
2502 unsigned ARMPCLabelIndex = AFI->createPICLabelUId();
2503 ARMConstantPoolValue *CPV = ARMConstantPoolSymbol::Create(
2504 *DAG.getContext(), Sym, ARMPCLabelIndex, PCAdj, ARMCP::GOT_PREL,
2505 /*AddCurrentAddress=*/true);
2506 SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVt, Align(4));
2507 CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr);
2508 SDValue GOTOffset = DAG.getLoad(
2509 PtrVt, dl, DAG.getEntryNode(), CPAddr,
2511 SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, dl, MVT::i32);
2512 Callee = DAG.getNode(ARMISD::PIC_ADD, dl, PtrVt, GOTOffset, PICLabel);
2513 Callee =
2514 DAG.getLoad(PtrVt, dl, DAG.getEntryNode(), Callee,
2516 } else {
2517 // Neither execute-only nor PIC: load the address from a constant pool.
2518 unsigned ARMPCLabelIndex = AFI->createPICLabelUId();
2519 ARMConstantPoolValue *CPV = ARMConstantPoolSymbol::Create(
2520 *DAG.getContext(), Sym, ARMPCLabelIndex, 0);
2521
2522 // Get the address of the callee into a register
2523 SDValue Addr = DAG.getTargetConstantPool(CPV, PtrVt, Align(4));
2524 Addr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Addr);
2525 Callee = DAG.getLoad(
2526 PtrVt, dl, DAG.getEntryNode(), Addr,
2528 }
2529 }
2530 } else if (isa<GlobalAddressSDNode>(Callee)) {
2531 if (!PreferIndirect) {
2532 isDirect = true;
2533 bool isDef = GVal->isStrongDefinitionForLinker();
2534
2535 // ARM call to a local ARM function is predicable.
2536 isLocalARMFunc = !Subtarget->isThumb() && (isDef || !ARMInterworking);
2537 // tBX takes a register source operand.
2538 if (isStub && Subtarget->isThumb1Only() && !Subtarget->hasV5TOps()) {
2539 assert(TT.isOSBinFormatMachO() && "WrapperPIC use on non-MachO?");
2540 Callee = DAG.getNode(
2541 ARMISD::WrapperPIC, dl, PtrVt,
2542 DAG.getTargetGlobalAddress(GVal, dl, PtrVt, 0, ARMII::MO_NONLAZY));
2543 Callee = DAG.getLoad(
2544 PtrVt, dl, DAG.getEntryNode(), Callee,
2548 } else if (Subtarget->isTargetCOFF()) {
2549 assert(Subtarget->isTargetWindows() &&
2550 "Windows is the only supported COFF target");
2551 unsigned TargetFlags = ARMII::MO_NO_FLAG;
2552 if (GVal->hasDLLImportStorageClass())
2553 TargetFlags = ARMII::MO_DLLIMPORT;
2554 else if (!TM.shouldAssumeDSOLocal(GVal))
2555 TargetFlags = ARMII::MO_COFFSTUB;
2556 Callee = DAG.getTargetGlobalAddress(GVal, dl, PtrVt, /*offset=*/0,
2557 TargetFlags);
2558 if (TargetFlags & (ARMII::MO_DLLIMPORT | ARMII::MO_COFFSTUB))
2559 Callee =
2560 DAG.getLoad(PtrVt, dl, DAG.getEntryNode(),
2561 DAG.getNode(ARMISD::Wrapper, dl, PtrVt, Callee),
2563 } else {
2564 Callee = DAG.getTargetGlobalAddress(GVal, dl, PtrVt, 0, 0);
2565 }
2566 }
2567 } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
2568 isDirect = true;
2569 // tBX takes a register source operand.
2570 const char *Sym = S->getSymbol();
2571 if (isARMFunc && Subtarget->isThumb1Only() && !Subtarget->hasV5TOps()) {
2572 unsigned ARMPCLabelIndex = AFI->createPICLabelUId();
2573 ARMConstantPoolValue *CPV =
2575 ARMPCLabelIndex, 4);
2576 SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVt, Align(4));
2577 CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr);
2578 Callee = DAG.getLoad(
2579 PtrVt, dl, DAG.getEntryNode(), CPAddr,
2581 SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, dl, MVT::i32);
2582 Callee = DAG.getNode(ARMISD::PIC_ADD, dl, PtrVt, Callee, PICLabel);
2583 } else {
2584 Callee = DAG.getTargetExternalSymbol(Sym, PtrVt, 0);
2585 }
2586 }
2587
2588 if (isCmseNSCall) {
2589 assert(!isARMFunc && !isDirect &&
2590 "Cannot handle call to ARM function or direct call");
2591 if (NumBytes > 0) {
2592 DAG.getContext()->diagnose(
2593 DiagnosticInfoUnsupported(DAG.getMachineFunction().getFunction(),
2594 "call to non-secure function would require "
2595 "passing arguments on stack",
2596 dl.getDebugLoc()));
2597 }
2598 if (isStructRet) {
2599 DAG.getContext()->diagnose(DiagnosticInfoUnsupported(
2601 "call to non-secure function would return value through pointer",
2602 dl.getDebugLoc()));
2603 }
2604 }
2605
2606 // FIXME: handle tail calls differently.
2607 unsigned CallOpc;
2608 if (Subtarget->isThumb()) {
2609 if (GuardWithBTI)
2610 CallOpc = ARMISD::t2CALL_BTI;
2611 else if (isCmseNSCall)
2612 CallOpc = ARMISD::tSECALL;
2613 else if ((!isDirect || isARMFunc) && !Subtarget->hasV5TOps())
2614 CallOpc = ARMISD::CALL_NOLINK;
2615 else
2616 CallOpc = ARMISD::CALL;
2617 } else {
2618 if (!isDirect && !Subtarget->hasV5TOps())
2619 CallOpc = ARMISD::CALL_NOLINK;
2620 else if (doesNotRet && isDirect && Subtarget->hasRetAddrStack() &&
2621 // Emit regular call when code size is the priority
2622 !Subtarget->hasMinSize())
2623 // "mov lr, pc; b _foo" to avoid confusing the RSP
2624 CallOpc = ARMISD::CALL_NOLINK;
2625 else
2626 CallOpc = isLocalARMFunc ? ARMISD::CALL_PRED : ARMISD::CALL;
2627 }
2628
2629 // We don't usually want to end the call-sequence here because we would tidy
2630 // the frame up *after* the call, however in the ABI-changing tail-call case
2631 // we've carefully laid out the parameters so that when sp is reset they'll be
2632 // in the correct location.
2633 if (isTailCall && !isSibCall) {
2634 Chain = DAG.getCALLSEQ_END(Chain, 0, 0, InGlue, dl);
2635 InGlue = Chain.getValue(1);
2636 }
2637
2638 std::vector<SDValue> Ops;
2639 Ops.push_back(Chain);
2640 Ops.push_back(Callee);
2641
2642 if (isTailCall) {
2643 Ops.push_back(DAG.getSignedTargetConstant(SPDiff, dl, MVT::i32));
2644 }
2645
2646 // Add argument registers to the end of the list so that they are known live
2647 // into the call.
2648 for (const auto &[Reg, N] : RegsToPass)
2649 Ops.push_back(DAG.getRegister(Reg, N.getValueType()));
2650
2651 // Add a register mask operand representing the call-preserved registers.
2652 const uint32_t *Mask;
2653 const ARMBaseRegisterInfo *ARI = Subtarget->getRegisterInfo();
2654 if (isThisReturn) {
2655 // For 'this' returns, use the R0-preserving mask if applicable
2656 Mask = ARI->getThisReturnPreservedMask(MF, CallConv);
2657 if (!Mask) {
2658 // Set isThisReturn to false if the calling convention is not one that
2659 // allows 'returned' to be modeled in this way, so LowerCallResult does
2660 // not try to pass 'this' straight through
2661 isThisReturn = false;
2662 Mask = ARI->getCallPreservedMask(MF, CallConv);
2663 }
2664 } else
2665 Mask = ARI->getCallPreservedMask(MF, CallConv);
2666
2667 assert(Mask && "Missing call preserved mask for calling convention");
2668 Ops.push_back(DAG.getRegisterMask(Mask));
2669
2670 if (InGlue.getNode())
2671 Ops.push_back(InGlue);
2672
2673 if (isTailCall) {
2675 SDValue Ret = DAG.getNode(ARMISD::TC_RETURN, dl, MVT::Other, Ops);
2676 if (CLI.CFIType)
2677 Ret.getNode()->setCFIType(CLI.CFIType->getZExtValue());
2678 DAG.addNoMergeSiteInfo(Ret.getNode(), CLI.NoMerge);
2679 DAG.addCallSiteInfo(Ret.getNode(), std::move(CSInfo));
2680 return Ret;
2681 }
2682
2683 // Returns a chain and a flag for retval copy to use.
2684 Chain = DAG.getNode(CallOpc, dl, {MVT::Other, MVT::Glue}, Ops);
2685 if (CLI.CFIType)
2686 Chain.getNode()->setCFIType(CLI.CFIType->getZExtValue());
2687 DAG.addNoMergeSiteInfo(Chain.getNode(), CLI.NoMerge);
2688 InGlue = Chain.getValue(1);
2689 DAG.addCallSiteInfo(Chain.getNode(), std::move(CSInfo));
2690
2691 // If we're guaranteeing tail-calls will be honoured, the callee must
2692 // pop its own argument stack on return. But this call is *not* a tail call so
2693 // we need to undo that after it returns to restore the status-quo.
2694 bool TailCallOpt = getTargetMachine().Options.GuaranteedTailCallOpt;
2695 uint64_t CalleePopBytes =
2696 canGuaranteeTCO(CallConv, TailCallOpt) ? alignTo(NumBytes, 16) : -1U;
2697
2698 Chain = DAG.getCALLSEQ_END(Chain, NumBytes, CalleePopBytes, InGlue, dl);
2699 if (!Ins.empty())
2700 InGlue = Chain.getValue(1);
2701
2702 // Handle result values, copying them out of physregs into vregs that we
2703 // return.
2704 return LowerCallResult(Chain, InGlue, CallConv, isVarArg, Ins, dl, DAG,
2705 InVals, isThisReturn,
2706 isThisReturn ? OutVals[0] : SDValue(), isCmseNSCall);
2707}
2708
2709/// HandleByVal - Every parameter *after* a byval parameter is passed
2710/// on the stack. Remember the next parameter register to allocate,
2711/// and then confiscate the rest of the parameter registers to insure
2712/// this.
2713void ARMTargetLowering::HandleByVal(CCState *State, unsigned &Size,
2714 Align Alignment) const {
2715 // Byval (as with any stack) slots are always at least 4 byte aligned.
2716 Alignment = std::max(Alignment, Align(4));
2717
2718 MCRegister Reg = State->AllocateReg(GPRArgRegs);
2719 if (!Reg)
2720 return;
2721
2722 unsigned AlignInRegs = Alignment.value() / 4;
2723 unsigned Waste = (ARM::R4 - Reg) % AlignInRegs;
2724 for (unsigned i = 0; i < Waste; ++i)
2725 Reg = State->AllocateReg(GPRArgRegs);
2726
2727 if (!Reg)
2728 return;
2729
2730 unsigned Excess = 4 * (ARM::R4 - Reg);
2731
2732 // Special case when NSAA != SP and parameter size greater than size of
2733 // all remained GPR regs. In that case we can't split parameter, we must
2734 // send it to stack. We also must set NCRN to R4, so waste all
2735 // remained registers.
2736 const unsigned NSAAOffset = State->getStackSize();
2737 if (NSAAOffset != 0 && Size > Excess) {
2738 while (State->AllocateReg(GPRArgRegs))
2739 ;
2740 return;
2741 }
2742
2743 // First register for byval parameter is the first register that wasn't
2744 // allocated before this method call, so it would be "reg".
2745 // If parameter is small enough to be saved in range [reg, r4), then
2746 // the end (first after last) register would be reg + param-size-in-regs,
2747 // else parameter would be splitted between registers and stack,
2748 // end register would be r4 in this case.
2749 unsigned ByValRegBegin = Reg;
2750 unsigned ByValRegEnd = std::min<unsigned>(Reg + Size / 4, ARM::R4);
2751 State->addInRegsParamInfo(ByValRegBegin, ByValRegEnd);
2752 // Note, first register is allocated in the beginning of function already,
2753 // allocate remained amount of registers we need.
2754 for (unsigned i = Reg + 1; i != ByValRegEnd; ++i)
2755 State->AllocateReg(GPRArgRegs);
2756 // A byval parameter that is split between registers and memory needs its
2757 // size truncated here.
2758 // In the case where the entire structure fits in registers, we set the
2759 // size in memory to zero.
2760 Size = std::max<int>(Size - Excess, 0);
2761}
2762
2763/// IsEligibleForTailCallOptimization - Check whether the call is eligible
2764/// for tail call optimization. Targets which want to do tail call
2765/// optimization should implement this function. Note that this function also
2766/// processes musttail calls, so when this function returns false on a valid
2767/// musttail call, a fatal backend error occurs.
2768bool ARMTargetLowering::IsEligibleForTailCallOptimization(
2770 SmallVectorImpl<CCValAssign> &ArgLocs, const bool isIndirect) const {
2771 CallingConv::ID CalleeCC = CLI.CallConv;
2772 SDValue Callee = CLI.Callee;
2773 bool isVarArg = CLI.IsVarArg;
2774 const SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
2775 const SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
2776 const SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins;
2777 const SelectionDAG &DAG = CLI.DAG;
2779 const Function &CallerF = MF.getFunction();
2780 CallingConv::ID CallerCC = CallerF.getCallingConv();
2781
2782 assert(Subtarget->supportsTailCall());
2783
2784 // Indirect tail-calls require a register to hold the target address. That
2785 // register must be:
2786 // * Allocatable (i.e. r0-r7 if the target is Thumb1).
2787 // * Not callee-saved, so must be one of r0-r3 or r12.
2788 // * Not used to hold an argument to the tail-called function, which might be
2789 // in r0-r3.
2790 // * Not used to hold the return address authentication code, which is in r12
2791 // if enabled.
2792 // Sometimes, no register matches all of these conditions, so we can't do a
2793 // tail-call.
2794 if (!isa<GlobalAddressSDNode>(Callee.getNode()) || isIndirect) {
2795 SmallSet<MCPhysReg, 5> AddressRegisters = {ARM::R0, ARM::R1, ARM::R2,
2796 ARM::R3};
2797 if (!(Subtarget->isThumb1Only() ||
2798 MF.getInfo<ARMFunctionInfo>()->shouldSignReturnAddress(true)))
2799 AddressRegisters.insert(ARM::R12);
2800 for (const CCValAssign &AL : ArgLocs)
2801 if (AL.isRegLoc())
2802 AddressRegisters.erase(AL.getLocReg());
2803 if (AddressRegisters.empty()) {
2804 LLVM_DEBUG(dbgs() << "false (no reg to hold function pointer)\n");
2805 return false;
2806 }
2807 }
2808
2809 // Look for obvious safe cases to perform tail call optimization that do not
2810 // require ABI changes. This is what gcc calls sibcall.
2811
2812 // Exception-handling functions need a special set of instructions to indicate
2813 // a return to the hardware. Tail-calling another function would probably
2814 // break this.
2815 if (CallerF.hasFnAttribute("interrupt")) {
2816 LLVM_DEBUG(dbgs() << "false (interrupt attribute)\n");
2817 return false;
2818 }
2819
2820 if (canGuaranteeTCO(CalleeCC,
2821 getTargetMachine().Options.GuaranteedTailCallOpt)) {
2822 LLVM_DEBUG(dbgs() << (CalleeCC == CallerCC ? "true" : "false")
2823 << " (guaranteed tail-call CC)\n");
2824 return CalleeCC == CallerCC;
2825 }
2826
2827 // Also avoid sibcall optimization if either caller or callee uses struct
2828 // return semantics.
2829 bool isCalleeStructRet = Outs.empty() ? false : Outs[0].Flags.isSRet();
2830 bool isCallerStructRet = MF.getFunction().hasStructRetAttr();
2831 if (isCalleeStructRet != isCallerStructRet) {
2832 LLVM_DEBUG(dbgs() << "false (struct-ret)\n");
2833 return false;
2834 }
2835
2836 // Externally-defined functions with weak linkage should not be
2837 // tail-called on ARM when the OS does not support dynamic
2838 // pre-emption of symbols, as the AAELF spec requires normal calls
2839 // to undefined weak functions to be replaced with a NOP or jump to the
2840 // next instruction. The behaviour of branch instructions in this
2841 // situation (as used for tail calls) is implementation-defined, so we
2842 // cannot rely on the linker replacing the tail call with a return.
2843 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
2844 const GlobalValue *GV = G->getGlobal();
2845 const Triple &TT = getTargetMachine().getTargetTriple();
2846 if (GV->hasExternalWeakLinkage() &&
2847 (!TT.isOSWindows() || TT.isOSBinFormatELF() ||
2848 TT.isOSBinFormatMachO())) {
2849 LLVM_DEBUG(dbgs() << "false (external weak linkage)\n");
2850 return false;
2851 }
2852 }
2853
2854 // Check that the call results are passed in the same way.
2855 LLVMContext &C = *DAG.getContext();
2857 getEffectiveCallingConv(CalleeCC, isVarArg),
2858 getEffectiveCallingConv(CallerCC, CallerF.isVarArg()), MF, C, Ins,
2859 CCAssignFnForReturn(CalleeCC, isVarArg),
2860 CCAssignFnForReturn(CallerCC, CallerF.isVarArg()))) {
2861 LLVM_DEBUG(dbgs() << "false (incompatible results)\n");
2862 return false;
2863 }
2864 // The callee has to preserve all registers the caller needs to preserve.
2865 const ARMBaseRegisterInfo *TRI = Subtarget->getRegisterInfo();
2866 const uint32_t *CallerPreserved = TRI->getCallPreservedMask(MF, CallerCC);
2867 if (CalleeCC != CallerCC) {
2868 const uint32_t *CalleePreserved = TRI->getCallPreservedMask(MF, CalleeCC);
2869 if (!TRI->regmaskSubsetEqual(CallerPreserved, CalleePreserved)) {
2870 LLVM_DEBUG(dbgs() << "false (not all registers preserved)\n");
2871 return false;
2872 }
2873 }
2874
2875 // If Caller's vararg argument has been split between registers and stack, do
2876 // not perform tail call, since part of the argument is in caller's local
2877 // frame.
2878 const ARMFunctionInfo *AFI_Caller = MF.getInfo<ARMFunctionInfo>();
2879 if (CLI.IsVarArg && AFI_Caller->getArgRegsSaveSize()) {
2880 LLVM_DEBUG(dbgs() << "false (arg reg save area)\n");
2881 return false;
2882 }
2883
2884 // If the callee takes no arguments then go on to check the results of the
2885 // call.
2886 const MachineRegisterInfo &MRI = MF.getRegInfo();
2887 if (!parametersInCSRMatch(MRI, CallerPreserved, ArgLocs, OutVals)) {
2888 LLVM_DEBUG(dbgs() << "false (parameters in CSRs do not match)\n");
2889 return false;
2890 }
2891
2892 // If the stack arguments for this call do not fit into our own save area then
2893 // the call cannot be made tail.
2894 if (CCInfo.getStackSize() > AFI_Caller->getArgumentStackSize())
2895 return false;
2896
2897 LLVM_DEBUG(dbgs() << "true\n");
2898 return true;
2899}
2900
2901bool
2902ARMTargetLowering::CanLowerReturn(CallingConv::ID CallConv,
2903 MachineFunction &MF, bool isVarArg,
2905 LLVMContext &Context, const Type *RetTy) const {
2907 CCState CCInfo(CallConv, isVarArg, MF, RVLocs, Context);
2908 return CCInfo.CheckReturn(Outs, CCAssignFnForReturn(CallConv, isVarArg));
2909}
2910
2912 const SDLoc &DL, SelectionDAG &DAG) {
2913 const MachineFunction &MF = DAG.getMachineFunction();
2914 const Function &F = MF.getFunction();
2915
2916 StringRef IntKind = F.getFnAttribute("interrupt").getValueAsString();
2917
2918 // See ARM ARM v7 B1.8.3. On exception entry LR is set to a possibly offset
2919 // version of the "preferred return address". These offsets affect the return
2920 // instruction if this is a return from PL1 without hypervisor extensions.
2921 // IRQ/FIQ: +4 "subs pc, lr, #4"
2922 // SWI: 0 "subs pc, lr, #0"
2923 // ABORT: +4 "subs pc, lr, #4"
2924 // UNDEF: +4/+2 "subs pc, lr, #0"
2925 // UNDEF varies depending on where the exception came from ARM or Thumb
2926 // mode. Alongside GCC, we throw our hands up in disgust and pretend it's 0.
2927
2928 int64_t LROffset;
2929 if (IntKind == "" || IntKind == "IRQ" || IntKind == "FIQ" ||
2930 IntKind == "ABORT")
2931 LROffset = 4;
2932 else if (IntKind == "SWI" || IntKind == "UNDEF")
2933 LROffset = 0;
2934 else
2935 report_fatal_error("Unsupported interrupt attribute. If present, value "
2936 "must be one of: IRQ, FIQ, SWI, ABORT or UNDEF");
2937
2938 RetOps.insert(RetOps.begin() + 1,
2939 DAG.getConstant(LROffset, DL, MVT::i32, false));
2940
2941 return DAG.getNode(ARMISD::INTRET_GLUE, DL, MVT::Other, RetOps);
2942}
2943
2944SDValue
2945ARMTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
2946 bool isVarArg,
2948 const SmallVectorImpl<SDValue> &OutVals,
2949 const SDLoc &dl, SelectionDAG &DAG) const {
2950 // CCValAssign - represent the assignment of the return value to a location.
2952
2953 // CCState - Info about the registers and stack slots.
2954 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), RVLocs,
2955 *DAG.getContext());
2956
2957 // Analyze outgoing return values.
2958 CCInfo.AnalyzeReturn(Outs, CCAssignFnForReturn(CallConv, isVarArg));
2959
2960 SDValue Glue;
2962 RetOps.push_back(Chain); // Operand #0 = Chain (updated below)
2963 bool isLittleEndian = Subtarget->isLittle();
2964
2966 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
2967 AFI->setReturnRegsCount(RVLocs.size());
2968
2969 // Report error if cmse entry function returns structure through first ptr arg.
2970 if (AFI->isCmseNSEntryFunction() && MF.getFunction().hasStructRetAttr()) {
2971 // Note: using an empty SDLoc(), as the first line of the function is a
2972 // better place to report than the last line.
2973 DAG.getContext()->diagnose(DiagnosticInfoUnsupported(
2975 "secure entry function would return value through pointer",
2976 SDLoc().getDebugLoc()));
2977 }
2978
2979 // Copy the result values into the output registers.
2980 for (unsigned i = 0, realRVLocIdx = 0;
2981 i != RVLocs.size();
2982 ++i, ++realRVLocIdx) {
2983 CCValAssign &VA = RVLocs[i];
2984 assert(VA.isRegLoc() && "Can only return in registers!");
2985
2986 SDValue Arg = OutVals[realRVLocIdx];
2987 bool ReturnF16 = false;
2988
2989 if (Subtarget->hasFullFP16() && Subtarget->isTargetHardFloat()) {
2990 // Half-precision return values can be returned like this:
2991 //
2992 // t11 f16 = fadd ...
2993 // t12: i16 = bitcast t11
2994 // t13: i32 = zero_extend t12
2995 // t14: f32 = bitcast t13 <~~~~~~~ Arg
2996 //
2997 // to avoid code generation for bitcasts, we simply set Arg to the node
2998 // that produces the f16 value, t11 in this case.
2999 //
3000 if (Arg.getValueType() == MVT::f32 && Arg.getOpcode() == ISD::BITCAST) {
3001 SDValue ZE = Arg.getOperand(0);
3002 if (ZE.getOpcode() == ISD::ZERO_EXTEND && ZE.getValueType() == MVT::i32) {
3003 SDValue BC = ZE.getOperand(0);
3004 if (BC.getOpcode() == ISD::BITCAST && BC.getValueType() == MVT::i16) {
3005 Arg = BC.getOperand(0);
3006 ReturnF16 = true;
3007 }
3008 }
3009 }
3010 }
3011
3012 switch (VA.getLocInfo()) {
3013 default: llvm_unreachable("Unknown loc info!");
3014 case CCValAssign::Full: break;
3015 case CCValAssign::BCvt:
3016 if (!ReturnF16)
3017 Arg = DAG.getNode(ISD::BITCAST, dl, VA.getLocVT(), Arg);
3018 break;
3019 }
3020
3021 // Mask f16 arguments if this is a CMSE nonsecure entry.
3022 auto RetVT = Outs[realRVLocIdx].ArgVT;
3023 if (AFI->isCmseNSEntryFunction() && (RetVT == MVT::f16)) {
3024 if (VA.needsCustom() && VA.getValVT() == MVT::f16) {
3025 Arg = MoveFromHPR(dl, DAG, VA.getLocVT(), VA.getValVT(), Arg);
3026 } else {
3027 auto LocBits = VA.getLocVT().getSizeInBits();
3028 auto MaskValue = APInt::getLowBitsSet(LocBits, RetVT.getSizeInBits());
3029 SDValue Mask =
3030 DAG.getConstant(MaskValue, dl, MVT::getIntegerVT(LocBits));
3031 Arg = DAG.getNode(ISD::BITCAST, dl, MVT::getIntegerVT(LocBits), Arg);
3032 Arg = DAG.getNode(ISD::AND, dl, MVT::getIntegerVT(LocBits), Arg, Mask);
3033 Arg = DAG.getNode(ISD::BITCAST, dl, VA.getLocVT(), Arg);
3034 }
3035 }
3036
3037 if (VA.needsCustom() &&
3038 (VA.getLocVT() == MVT::v2f64 || VA.getLocVT() == MVT::f64)) {
3039 if (VA.getLocVT() == MVT::v2f64) {
3040 // Extract the first half and return it in two registers.
3041 SDValue Half = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f64, Arg,
3042 DAG.getConstant(0, dl, MVT::i32));
3043 SDValue HalfGPRs = DAG.getNode(ARMISD::VMOVRRD, dl,
3044 DAG.getVTList(MVT::i32, MVT::i32), Half);
3045
3046 Chain =
3047 DAG.getCopyToReg(Chain, dl, VA.getLocReg(),
3048 HalfGPRs.getValue(isLittleEndian ? 0 : 1), Glue);
3049 Glue = Chain.getValue(1);
3050 RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
3051 VA = RVLocs[++i]; // skip ahead to next loc
3052 Chain =
3053 DAG.getCopyToReg(Chain, dl, VA.getLocReg(),
3054 HalfGPRs.getValue(isLittleEndian ? 1 : 0), Glue);
3055 Glue = Chain.getValue(1);
3056 RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
3057 VA = RVLocs[++i]; // skip ahead to next loc
3058
3059 // Extract the 2nd half and fall through to handle it as an f64 value.
3060 Arg = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f64, Arg,
3061 DAG.getConstant(1, dl, MVT::i32));
3062 }
3063 // Legalize ret f64 -> ret 2 x i32. We always have fmrrd if f64 is
3064 // available.
3065 SDValue fmrrd = DAG.getNode(ARMISD::VMOVRRD, dl,
3066 DAG.getVTList(MVT::i32, MVT::i32), Arg);
3067 Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(),
3068 fmrrd.getValue(isLittleEndian ? 0 : 1), Glue);
3069 Glue = Chain.getValue(1);
3070 RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
3071 VA = RVLocs[++i]; // skip ahead to next loc
3072 Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(),
3073 fmrrd.getValue(isLittleEndian ? 1 : 0), Glue);
3074 } else
3075 Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), Arg, Glue);
3076
3077 // Guarantee that all emitted copies are
3078 // stuck together, avoiding something bad.
3079 Glue = Chain.getValue(1);
3080 RetOps.push_back(DAG.getRegister(
3081 VA.getLocReg(), ReturnF16 ? Arg.getValueType() : VA.getLocVT()));
3082 }
3083 const ARMBaseRegisterInfo *TRI = Subtarget->getRegisterInfo();
3084 const MCPhysReg *I =
3085 TRI->getCalleeSavedRegsViaCopy(&DAG.getMachineFunction());
3086 if (I) {
3087 for (; *I; ++I) {
3088 if (ARM::GPRRegClass.contains(*I))
3089 RetOps.push_back(DAG.getRegister(*I, MVT::i32));
3090 else if (ARM::DPRRegClass.contains(*I))
3092 else
3093 llvm_unreachable("Unexpected register class in CSRsViaCopy!");
3094 }
3095 }
3096
3097 // Update chain and glue.
3098 RetOps[0] = Chain;
3099 if (Glue.getNode())
3100 RetOps.push_back(Glue);
3101
3102 // CPUs which aren't M-class use a special sequence to return from
3103 // exceptions (roughly, any instruction setting pc and cpsr simultaneously,
3104 // though we use "subs pc, lr, #N").
3105 //
3106 // M-class CPUs actually use a normal return sequence with a special
3107 // (hardware-provided) value in LR, so the normal code path works.
3108 if (DAG.getMachineFunction().getFunction().hasFnAttribute("interrupt") &&
3109 !Subtarget->isMClass()) {
3110 if (Subtarget->isThumb1Only())
3111 report_fatal_error("interrupt attribute is not supported in Thumb1");
3112 return LowerInterruptReturn(RetOps, dl, DAG);
3113 }
3114
3115 unsigned RetNode =
3116 AFI->isCmseNSEntryFunction() ? ARMISD::SERET_GLUE : ARMISD::RET_GLUE;
3117 return DAG.getNode(RetNode, dl, MVT::Other, RetOps);
3118}
3119
3120bool ARMTargetLowering::isUsedByReturnOnly(SDNode *N, SDValue &Chain) const {
3121 if (N->getNumValues() != 1)
3122 return false;
3123 if (!N->hasNUsesOfValue(1, 0))
3124 return false;
3125
3126 SDValue TCChain = Chain;
3127 SDNode *Copy = *N->user_begin();
3128 if (Copy->getOpcode() == ISD::CopyToReg) {
3129 // If the copy has a glue operand, we conservatively assume it isn't safe to
3130 // perform a tail call.
3131 if (Copy->getOperand(Copy->getNumOperands()-1).getValueType() == MVT::Glue)
3132 return false;
3133 TCChain = Copy->getOperand(0);
3134 } else if (Copy->getOpcode() == ARMISD::VMOVRRD) {
3135 SDNode *VMov = Copy;
3136 // f64 returned in a pair of GPRs.
3137 SmallPtrSet<SDNode*, 2> Copies;
3138 for (SDNode *U : VMov->users()) {
3139 if (U->getOpcode() != ISD::CopyToReg)
3140 return false;
3141 Copies.insert(U);
3142 }
3143 if (Copies.size() > 2)
3144 return false;
3145
3146 for (SDNode *U : VMov->users()) {
3147 SDValue UseChain = U->getOperand(0);
3148 if (Copies.count(UseChain.getNode()))
3149 // Second CopyToReg
3150 Copy = U;
3151 else {
3152 // We are at the top of this chain.
3153 // If the copy has a glue operand, we conservatively assume it
3154 // isn't safe to perform a tail call.
3155 if (U->getOperand(U->getNumOperands() - 1).getValueType() == MVT::Glue)
3156 return false;
3157 // First CopyToReg
3158 TCChain = UseChain;
3159 }
3160 }
3161 } else if (Copy->getOpcode() == ISD::BITCAST) {
3162 // f32 returned in a single GPR.
3163 if (!Copy->hasOneUse())
3164 return false;
3165 Copy = *Copy->user_begin();
3166 if (Copy->getOpcode() != ISD::CopyToReg || !Copy->hasNUsesOfValue(1, 0))
3167 return false;
3168 // If the copy has a glue operand, we conservatively assume it isn't safe to
3169 // perform a tail call.
3170 if (Copy->getOperand(Copy->getNumOperands()-1).getValueType() == MVT::Glue)
3171 return false;
3172 TCChain = Copy->getOperand(0);
3173 } else {
3174 return false;
3175 }
3176
3177 bool HasRet = false;
3178 for (const SDNode *U : Copy->users()) {
3179 if (U->getOpcode() != ARMISD::RET_GLUE &&
3180 U->getOpcode() != ARMISD::INTRET_GLUE)
3181 return false;
3182 HasRet = true;
3183 }
3184
3185 if (!HasRet)
3186 return false;
3187
3188 Chain = TCChain;
3189 return true;
3190}
3191
3192bool ARMTargetLowering::mayBeEmittedAsTailCall(const CallInst *CI) const {
3193 if (!Subtarget->supportsTailCall())
3194 return false;
3195
3196 if (!CI->isTailCall())
3197 return false;
3198
3199 return true;
3200}
3201
3202// Trying to write a 64 bit value so need to split into two 32 bit values first,
3203// and pass the lower and high parts through.
3205 SDLoc DL(Op);
3206 SDValue WriteValue = Op->getOperand(2);
3207
3208 // This function is only supposed to be called for i64 type argument.
3209 assert(WriteValue.getValueType() == MVT::i64
3210 && "LowerWRITE_REGISTER called for non-i64 type argument.");
3211
3212 SDValue Lo, Hi;
3213 std::tie(Lo, Hi) = DAG.SplitScalar(WriteValue, DL, MVT::i32, MVT::i32);
3214 SDValue Ops[] = { Op->getOperand(0), Op->getOperand(1), Lo, Hi };
3215 return DAG.getNode(ISD::WRITE_REGISTER, DL, MVT::Other, Ops);
3216}
3217
3218// ConstantPool, JumpTable, GlobalAddress, and ExternalSymbol are lowered as
3219// their target counterpart wrapped in the ARMISD::Wrapper node. Suppose N is
3220// one of the above mentioned nodes. It has to be wrapped because otherwise
3221// Select(N) returns N. So the raw TargetGlobalAddress nodes, etc. can only
3222// be used to form addressing mode. These wrapped nodes will be selected
3223// into MOVi.
3224SDValue ARMTargetLowering::LowerConstantPool(SDValue Op,
3225 SelectionDAG &DAG) const {
3226 EVT PtrVT = Op.getValueType();
3227 // FIXME there is no actual debug info here
3228 SDLoc dl(Op);
3229 ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op);
3230 SDValue Res;
3231
3232 // When generating execute-only code Constant Pools must be promoted to the
3233 // global data section. It's a bit ugly that we can't share them across basic
3234 // blocks, but this way we guarantee that execute-only behaves correct with
3235 // position-independent addressing modes.
3236 if (Subtarget->genExecuteOnly()) {
3237 auto AFI = DAG.getMachineFunction().getInfo<ARMFunctionInfo>();
3238 auto *T = CP->getType();
3239 auto C = const_cast<Constant*>(CP->getConstVal());
3240 auto M = DAG.getMachineFunction().getFunction().getParent();
3241 auto GV = new GlobalVariable(
3242 *M, T, /*isConstant=*/true, GlobalVariable::InternalLinkage, C,
3243 Twine(DAG.getDataLayout().getInternalSymbolPrefix()) + "CP" +
3244 Twine(DAG.getMachineFunction().getFunctionNumber()) + "_" +
3245 Twine(AFI->createPICLabelUId()));
3246 SDValue GA = DAG.getTargetGlobalAddress(GV, dl, PtrVT);
3247 return LowerGlobalAddress(GA, DAG);
3248 }
3249
3250 // The 16-bit ADR instruction can only encode offsets that are multiples of 4,
3251 // so we need to align to at least 4 bytes when we don't have 32-bit ADR.
3252 Align CPAlign = CP->getAlign();
3253 if (Subtarget->isThumb1Only())
3254 CPAlign = std::max(CPAlign, Align(4));
3256 Res =
3257 DAG.getTargetConstantPool(CP->getMachineCPVal(), PtrVT, CPAlign);
3258 else
3259 Res = DAG.getTargetConstantPool(CP->getConstVal(), PtrVT, CPAlign);
3260 return DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Res);
3261}
3262
3264 // If we don't have a 32-bit pc-relative branch instruction then the jump
3265 // table consists of block addresses. Usually this is inline, but for
3266 // execute-only it must be placed out-of-line.
3267 if (Subtarget->genExecuteOnly() && !Subtarget->hasV8MBaselineOps())
3270}
3271
3272SDValue ARMTargetLowering::LowerBlockAddress(SDValue Op,
3273 SelectionDAG &DAG) const {
3276 unsigned ARMPCLabelIndex = 0;
3277 SDLoc DL(Op);
3278 EVT PtrVT = getPointerTy(DAG.getDataLayout());
3279 const BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress();
3280 SDValue CPAddr;
3281 bool IsPositionIndependent = isPositionIndependent() || Subtarget->isROPI();
3282 if (!IsPositionIndependent) {
3283 CPAddr = DAG.getTargetConstantPool(BA, PtrVT, Align(4));
3284 } else {
3285 unsigned PCAdj = Subtarget->isThumb() ? 4 : 8;
3286 ARMPCLabelIndex = AFI->createPICLabelUId();
3288 ARMConstantPoolConstant::Create(BA, ARMPCLabelIndex,
3289 ARMCP::CPBlockAddress, PCAdj);
3290 CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, Align(4));
3291 }
3292 CPAddr = DAG.getNode(ARMISD::Wrapper, DL, PtrVT, CPAddr);
3293 SDValue Result = DAG.getLoad(
3294 PtrVT, DL, DAG.getEntryNode(), CPAddr,
3296 if (!IsPositionIndependent)
3297 return Result;
3298 SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, DL, MVT::i32);
3299 return DAG.getNode(ARMISD::PIC_ADD, DL, PtrVT, Result, PICLabel);
3300}
3301
3302/// Convert a TLS address reference into the correct sequence of loads
3303/// and calls to compute the variable's address for Darwin, and return an
3304/// SDValue containing the final node.
3305
3306/// Darwin only has one TLS scheme which must be capable of dealing with the
3307/// fully general situation, in the worst case. This means:
3308/// + "extern __thread" declaration.
3309/// + Defined in a possibly unknown dynamic library.
3310///
3311/// The general system is that each __thread variable has a [3 x i32] descriptor
3312/// which contains information used by the runtime to calculate the address. The
3313/// only part of this the compiler needs to know about is the first word, which
3314/// contains a function pointer that must be called with the address of the
3315/// entire descriptor in "r0".
3316///
3317/// Since this descriptor may be in a different unit, in general access must
3318/// proceed along the usual ARM rules. A common sequence to produce is:
3319///
3320/// movw rT1, :lower16:_var$non_lazy_ptr
3321/// movt rT1, :upper16:_var$non_lazy_ptr
3322/// ldr r0, [rT1]
3323/// ldr rT2, [r0]
3324/// blx rT2
3325/// [...address now in r0...]
3326SDValue
3327ARMTargetLowering::LowerGlobalTLSAddressDarwin(SDValue Op,
3328 SelectionDAG &DAG) const {
3329 assert(getTargetMachine().getTargetTriple().isOSDarwin() &&
3330 "This function expects a Darwin target");
3331 SDLoc DL(Op);
3332
3333 // First step is to get the address of the actua global symbol. This is where
3334 // the TLS descriptor lives.
3335 SDValue DescAddr = LowerGlobalAddressDarwin(Op, DAG);
3336
3337 // The first entry in the descriptor is a function pointer that we must call
3338 // to obtain the address of the variable.
3339 SDValue Chain = DAG.getEntryNode();
3340 SDValue FuncTLVGet = DAG.getLoad(
3341 MVT::i32, DL, Chain, DescAddr,
3345 Chain = FuncTLVGet.getValue(1);
3346
3348 MachineFrameInfo &MFI = F.getFrameInfo();
3349 MFI.setAdjustsStack(true);
3350
3351 // TLS calls preserve all registers except those that absolutely must be
3352 // trashed: R0 (it takes an argument), LR (it's a call) and CPSR (let's not be
3353 // silly).
3354 auto TRI =
3356 auto ARI = static_cast<const ARMRegisterInfo *>(TRI);
3357 const uint32_t *Mask = ARI->getTLSCallPreservedMask(DAG.getMachineFunction());
3358
3359 // Finally, we can make the call. This is just a degenerate version of a
3360 // normal AArch64 call node: r0 takes the address of the descriptor, and
3361 // returns the address of the variable in this thread.
3362 Chain = DAG.getCopyToReg(Chain, DL, ARM::R0, DescAddr, SDValue());
3363 Chain =
3364 DAG.getNode(ARMISD::CALL, DL, DAG.getVTList(MVT::Other, MVT::Glue),
3365 Chain, FuncTLVGet, DAG.getRegister(ARM::R0, MVT::i32),
3366 DAG.getRegisterMask(Mask), Chain.getValue(1));
3367 return DAG.getCopyFromReg(Chain, DL, ARM::R0, MVT::i32, Chain.getValue(1));
3368}
3369
3370SDValue
3371ARMTargetLowering::LowerGlobalTLSAddressWindows(SDValue Op,
3372 SelectionDAG &DAG) const {
3373 assert(getTargetMachine().getTargetTriple().isOSWindows() &&
3374 "Windows specific TLS lowering");
3375
3376 SDValue Chain = DAG.getEntryNode();
3377 EVT PtrVT = getPointerTy(DAG.getDataLayout());
3378 SDLoc DL(Op);
3379
3380 // Load the current TEB (thread environment block)
3381 SDValue Ops[] = {Chain,
3382 DAG.getTargetConstant(Intrinsic::arm_mrc, DL, MVT::i32),
3383 DAG.getTargetConstant(15, DL, MVT::i32),
3384 DAG.getTargetConstant(0, DL, MVT::i32),
3385 DAG.getTargetConstant(13, DL, MVT::i32),
3386 DAG.getTargetConstant(0, DL, MVT::i32),
3387 DAG.getTargetConstant(2, DL, MVT::i32)};
3388 SDValue CurrentTEB = DAG.getNode(ISD::INTRINSIC_W_CHAIN, DL,
3389 DAG.getVTList(MVT::i32, MVT::Other), Ops);
3390
3391 SDValue TEB = CurrentTEB.getValue(0);
3392 Chain = CurrentTEB.getValue(1);
3393
3394 // Load the ThreadLocalStoragePointer from the TEB
3395 // A pointer to the TLS array is located at offset 0x2c from the TEB.
3396 SDValue TLSArray =
3397 DAG.getNode(ISD::ADD, DL, PtrVT, TEB, DAG.getIntPtrConstant(0x2c, DL));
3398 TLSArray = DAG.getLoad(PtrVT, DL, Chain, TLSArray, MachinePointerInfo());
3399
3400 // The pointer to the thread's TLS data area is at the TLS Index scaled by 4
3401 // offset into the TLSArray.
3402
3403 // Load the TLS index from the C runtime
3404 SDValue TLSIndex =
3405 DAG.getTargetExternalSymbol("_tls_index", PtrVT, ARMII::MO_NO_FLAG);
3406 TLSIndex = DAG.getNode(ARMISD::Wrapper, DL, PtrVT, TLSIndex);
3407 TLSIndex = DAG.getLoad(PtrVT, DL, Chain, TLSIndex, MachinePointerInfo());
3408
3409 SDValue Slot = DAG.getNode(ISD::SHL, DL, PtrVT, TLSIndex,
3410 DAG.getConstant(2, DL, MVT::i32));
3411 SDValue TLS = DAG.getLoad(PtrVT, DL, Chain,
3412 DAG.getNode(ISD::ADD, DL, PtrVT, TLSArray, Slot),
3413 MachinePointerInfo());
3414
3415 // Get the offset of the start of the .tls section (section base)
3416 const auto *GA = cast<GlobalAddressSDNode>(Op);
3417 auto *CPV = ARMConstantPoolConstant::Create(GA->getGlobal(), ARMCP::SECREL);
3418 SDValue Offset = DAG.getLoad(
3419 PtrVT, DL, Chain,
3420 DAG.getNode(ARMISD::Wrapper, DL, MVT::i32,
3421 DAG.getTargetConstantPool(CPV, PtrVT, Align(4))),
3423
3424 return DAG.getNode(ISD::ADD, DL, PtrVT, TLS, Offset);
3425}
3426
3427// Lower ISD::GlobalTLSAddress using the "general dynamic" model
3428SDValue
3429ARMTargetLowering::LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA,
3430 SelectionDAG &DAG) const {
3431 SDLoc dl(GA);
3432 EVT PtrVT = getPointerTy(DAG.getDataLayout());
3433 unsigned char PCAdj = Subtarget->isThumb() ? 4 : 8;
3435 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
3436 unsigned ARMPCLabelIndex = AFI->createPICLabelUId();
3437 ARMConstantPoolValue *CPV =
3438 ARMConstantPoolConstant::Create(GA->getGlobal(), ARMPCLabelIndex,
3439 ARMCP::CPValue, PCAdj, ARMCP::TLSGD, true);
3440 SDValue Argument = DAG.getTargetConstantPool(CPV, PtrVT, Align(4));
3441 Argument = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Argument);
3442 Argument = DAG.getLoad(
3443 PtrVT, dl, DAG.getEntryNode(), Argument,
3445 SDValue Chain = Argument.getValue(1);
3446
3447 SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, dl, MVT::i32);
3448 Argument = DAG.getNode(ARMISD::PIC_ADD, dl, PtrVT, Argument, PICLabel);
3449
3450 // call __tls_get_addr.
3452 Args.emplace_back(Argument, Type::getInt32Ty(*DAG.getContext()));
3453
3454 // FIXME: is there useful debug info available here?
3455 TargetLowering::CallLoweringInfo CLI(DAG);
3456 CLI.setDebugLoc(dl).setChain(Chain).setLibCallee(
3458 DAG.getExternalSymbol("__tls_get_addr", PtrVT), std::move(Args));
3459
3460 std::pair<SDValue, SDValue> CallResult = LowerCallTo(CLI);
3461 return CallResult.first;
3462}
3463
3464// Lower ISD::GlobalTLSAddress using the "initial exec" or
3465// "local exec" model.
3466SDValue
3467ARMTargetLowering::LowerToTLSExecModels(GlobalAddressSDNode *GA,
3468 SelectionDAG &DAG,
3469 TLSModel::Model model) const {
3470 const GlobalValue *GV = GA->getGlobal();
3471 SDLoc dl(GA);
3472 SDValue Offset;
3473 SDValue Chain = DAG.getEntryNode();
3474 EVT PtrVT = getPointerTy(DAG.getDataLayout());
3475 // Get the Thread Pointer
3476 SDValue ThreadPointer = DAG.getNode(ARMISD::THREAD_POINTER, dl, PtrVT);
3477
3478 if (model == TLSModel::InitialExec) {
3480 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
3481 unsigned ARMPCLabelIndex = AFI->createPICLabelUId();
3482 // Initial exec model.
3483 unsigned char PCAdj = Subtarget->isThumb() ? 4 : 8;
3484 ARMConstantPoolValue *CPV =
3485 ARMConstantPoolConstant::Create(GA->getGlobal(), ARMPCLabelIndex,
3487 true);
3488 Offset = DAG.getTargetConstantPool(CPV, PtrVT, Align(4));
3489 Offset = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Offset);
3490 Offset = DAG.getLoad(
3491 PtrVT, dl, Chain, Offset,
3493 Chain = Offset.getValue(1);
3494
3495 SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, dl, MVT::i32);
3496 Offset = DAG.getNode(ARMISD::PIC_ADD, dl, PtrVT, Offset, PICLabel);
3497
3498 Offset = DAG.getLoad(
3499 PtrVT, dl, Chain, Offset,
3501 } else {
3502 // local exec model
3503 assert(model == TLSModel::LocalExec);
3504 ARMConstantPoolValue *CPV =
3506 Offset = DAG.getTargetConstantPool(CPV, PtrVT, Align(4));
3507 Offset = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Offset);
3508 Offset = DAG.getLoad(
3509 PtrVT, dl, Chain, Offset,
3511 }
3512
3513 // The address of the thread local variable is the add of the thread
3514 // pointer with the offset of the variable.
3515 return DAG.getNode(ISD::ADD, dl, PtrVT, ThreadPointer, Offset);
3516}
3517
3518SDValue
3519ARMTargetLowering::LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const {
3520 GlobalAddressSDNode *GA = cast<GlobalAddressSDNode>(Op);
3521 if (DAG.getTarget().useEmulatedTLS())
3522 return LowerToTLSEmulatedModel(GA, DAG);
3523
3524 const Triple &TT = getTargetMachine().getTargetTriple();
3525 if (TT.isOSDarwin())
3526 return LowerGlobalTLSAddressDarwin(Op, DAG);
3527
3528 if (TT.isOSWindows())
3529 return LowerGlobalTLSAddressWindows(Op, DAG);
3530
3531 // TODO: implement the "local dynamic" model
3532 assert(TT.isOSBinFormatELF() && "Only ELF implemented here");
3534
3535 switch (model) {
3538 return LowerToTLSGeneralDynamicModel(GA, DAG);
3541 return LowerToTLSExecModels(GA, DAG, model);
3542 }
3543 llvm_unreachable("bogus TLS model");
3544}
3545
3546/// Return true if all users of V are within function F, looking through
3547/// ConstantExprs.
3548static bool allUsersAreInFunction(const Value *V, const Function *F) {
3549 SmallVector<const User*,4> Worklist(V->users());
3550 while (!Worklist.empty()) {
3551 auto *U = Worklist.pop_back_val();
3552 if (isa<ConstantExpr>(U)) {
3553 append_range(Worklist, U->users());
3554 continue;
3555 }
3556
3557 auto *I = dyn_cast<Instruction>(U);
3558 if (!I || I->getParent()->getParent() != F)
3559 return false;
3560 }
3561 return true;
3562}
3563
3565 const GlobalValue *GV, SelectionDAG &DAG,
3566 EVT PtrVT, const SDLoc &dl) {
3567 // If we're creating a pool entry for a constant global with unnamed address,
3568 // and the global is small enough, we can emit it inline into the constant pool
3569 // to save ourselves an indirection.
3570 //
3571 // This is a win if the constant is only used in one function (so it doesn't
3572 // need to be duplicated) or duplicating the constant wouldn't increase code
3573 // size (implying the constant is no larger than 4 bytes).
3574 const Function &F = DAG.getMachineFunction().getFunction();
3575
3576 // We rely on this decision to inline being idempotent and unrelated to the
3577 // use-site. We know that if we inline a variable at one use site, we'll
3578 // inline it elsewhere too (and reuse the constant pool entry). Fast-isel
3579 // doesn't know about this optimization, so bail out if it's enabled else
3580 // we could decide to inline here (and thus never emit the GV) but require
3581 // the GV from fast-isel generated code.
3584 return SDValue();
3585
3586 auto *GVar = dyn_cast<GlobalVariable>(GV);
3587 if (!GVar || !GVar->hasInitializer() ||
3588 !GVar->isConstant() || !GVar->hasGlobalUnnamedAddr() ||
3589 !GVar->hasLocalLinkage())
3590 return SDValue();
3591
3592 // If we inline a value that contains relocations, we move the relocations
3593 // from .data to .text. This is not allowed in position-independent code.
3594 auto *Init = GVar->getInitializer();
3595 if ((TLI->isPositionIndependent() || TLI->getSubtarget()->isROPI()) &&
3596 Init->needsDynamicRelocation())
3597 return SDValue();
3598
3599 // The constant islands pass can only really deal with alignment requests
3600 // <= 4 bytes and cannot pad constants itself. Therefore we cannot promote
3601 // any type wanting greater alignment requirements than 4 bytes. We also
3602 // can only promote constants that are multiples of 4 bytes in size or
3603 // are paddable to a multiple of 4. Currently we only try and pad constants
3604 // that are strings for simplicity.
3605 auto *CDAInit = dyn_cast<ConstantDataArray>(Init);
3606 unsigned Size = DAG.getDataLayout().getTypeAllocSize(Init->getType());
3607 Align PrefAlign = DAG.getDataLayout().getPreferredAlign(GVar);
3608 unsigned RequiredPadding = 4 - (Size % 4);
3609 bool PaddingPossible =
3610 RequiredPadding == 4 || (CDAInit && CDAInit->isString());
3611 if (!PaddingPossible || PrefAlign > 4 || Size > ConstpoolPromotionMaxSize ||
3612 Size == 0)
3613 return SDValue();
3614
3615 unsigned PaddedSize = Size + ((RequiredPadding == 4) ? 0 : RequiredPadding);
3617 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
3618
3619 // We can't bloat the constant pool too much, else the ConstantIslands pass
3620 // may fail to converge. If we haven't promoted this global yet (it may have
3621 // multiple uses), and promoting it would increase the constant pool size (Sz
3622 // > 4), ensure we have space to do so up to MaxTotal.
3623 if (!AFI->getGlobalsPromotedToConstantPool().count(GVar) && Size > 4)
3624 if (AFI->getPromotedConstpoolIncrease() + PaddedSize - 4 >=
3626 return SDValue();
3627
3628 // This is only valid if all users are in a single function; we can't clone
3629 // the constant in general. The LLVM IR unnamed_addr allows merging
3630 // constants, but not cloning them.
3631 //
3632 // We could potentially allow cloning if we could prove all uses of the
3633 // constant in the current function don't care about the address, like
3634 // printf format strings. But that isn't implemented for now.
3635 if (!allUsersAreInFunction(GVar, &F))
3636 return SDValue();
3637
3638 // We're going to inline this global. Pad it out if needed.
3639 if (RequiredPadding != 4) {
3640 StringRef S = CDAInit->getAsString();
3641
3643 std::copy(S.bytes_begin(), S.bytes_end(), V.begin());
3644 while (RequiredPadding--)
3645 V.push_back(0);
3647 }
3648
3649 auto CPVal = ARMConstantPoolConstant::Create(GVar, Init);
3650 SDValue CPAddr = DAG.getTargetConstantPool(CPVal, PtrVT, Align(4));
3651 if (!AFI->getGlobalsPromotedToConstantPool().count(GVar)) {
3654 PaddedSize - 4);
3655 }
3656 ++NumConstpoolPromoted;
3657 return DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr);
3658}
3659
3661 if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(GV))
3662 if (!(GV = GA->getAliaseeObject()))
3663 return false;
3664 if (const auto *V = dyn_cast<GlobalVariable>(GV))
3665 return V->isConstant();
3666 return isa<Function>(GV);
3667}
3668
3669SDValue ARMTargetLowering::LowerGlobalAddress(SDValue Op,
3670 SelectionDAG &DAG) const {
3671 switch (Subtarget->getTargetTriple().getObjectFormat()) {
3672 default: llvm_unreachable("unknown object format");
3673 case Triple::COFF:
3674 return LowerGlobalAddressWindows(Op, DAG);
3675 case Triple::ELF:
3676 return LowerGlobalAddressELF(Op, DAG);
3677 case Triple::MachO:
3678 return LowerGlobalAddressDarwin(Op, DAG);
3679 }
3680}
3681
3682SDValue ARMTargetLowering::LowerGlobalAddressELF(SDValue Op,
3683 SelectionDAG &DAG) const {
3684 EVT PtrVT = getPointerTy(DAG.getDataLayout());
3685 SDLoc dl(Op);
3686 const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
3687 bool IsRO = isReadOnly(GV);
3688
3689 // promoteToConstantPool only if not generating XO text section
3690 if (GV->isDSOLocal() && !Subtarget->genExecuteOnly())
3691 if (SDValue V = promoteToConstantPool(this, GV, DAG, PtrVT, dl))
3692 return V;
3693
3694 if (isPositionIndependent()) {
3695 SDValue G = DAG.getTargetGlobalAddress(
3696 GV, dl, PtrVT, 0, GV->isDSOLocal() ? 0 : ARMII::MO_GOT);
3697 SDValue Result = DAG.getNode(ARMISD::WrapperPIC, dl, PtrVT, G);
3698 if (!GV->isDSOLocal())
3699 Result =
3700 DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), Result,
3702 return Result;
3703 } else if (Subtarget->isROPI() && IsRO) {
3704 // PC-relative.
3705 SDValue G = DAG.getTargetGlobalAddress(GV, dl, PtrVT);
3706 SDValue Result = DAG.getNode(ARMISD::WrapperPIC, dl, PtrVT, G);
3707 return Result;
3708 } else if (Subtarget->isRWPI() && !IsRO) {
3709 // SB-relative.
3710 SDValue RelAddr;
3711 if (Subtarget->useMovt()) {
3712 ++NumMovwMovt;
3713 SDValue G = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0, ARMII::MO_SBREL);
3714 RelAddr = DAG.getNode(ARMISD::Wrapper, dl, PtrVT, G);
3715 } else { // use literal pool for address constant
3716 ARMConstantPoolValue *CPV =
3718 SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, Align(4));
3719 CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr);
3720 RelAddr = DAG.getLoad(
3721 PtrVT, dl, DAG.getEntryNode(), CPAddr,
3723 }
3724 SDValue SB = DAG.getCopyFromReg(DAG.getEntryNode(), dl, ARM::R9, PtrVT);
3725 SDValue Result = DAG.getNode(ISD::ADD, dl, PtrVT, SB, RelAddr);
3726 return Result;
3727 }
3728
3729 // If we have T2 ops, we can materialize the address directly via movt/movw
3730 // pair. This is always cheaper. If need to generate Execute Only code, and we
3731 // only have Thumb1 available, we can't use a constant pool and are forced to
3732 // use immediate relocations.
3733 if (Subtarget->useMovt() || Subtarget->genExecuteOnly()) {
3734 if (Subtarget->useMovt())
3735 ++NumMovwMovt;
3736 // FIXME: Once remat is capable of dealing with instructions with register
3737 // operands, expand this into two nodes.
3738 return DAG.getNode(ARMISD::Wrapper, dl, PtrVT,
3739 DAG.getTargetGlobalAddress(GV, dl, PtrVT));
3740 } else {
3741 SDValue CPAddr = DAG.getTargetConstantPool(GV, PtrVT, Align(4));
3742 CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr);
3743 return DAG.getLoad(
3744 PtrVT, dl, DAG.getEntryNode(), CPAddr,
3746 }
3747}
3748
3749SDValue ARMTargetLowering::LowerGlobalAddressDarwin(SDValue Op,
3750 SelectionDAG &DAG) const {
3751 assert(!Subtarget->isROPI() && !Subtarget->isRWPI() &&
3752 "ROPI/RWPI not currently supported for Darwin");
3753 EVT PtrVT = getPointerTy(DAG.getDataLayout());
3754 SDLoc dl(Op);
3755 const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
3756
3757 if (Subtarget->useMovt())
3758 ++NumMovwMovt;
3759
3760 // FIXME: Once remat is capable of dealing with instructions with register
3761 // operands, expand this into multiple nodes
3762 unsigned Wrapper =
3763 isPositionIndependent() ? ARMISD::WrapperPIC : ARMISD::Wrapper;
3764
3765 SDValue G = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0, ARMII::MO_NONLAZY);
3766 SDValue Result = DAG.getNode(Wrapper, dl, PtrVT, G);
3767
3768 if (Subtarget->isGVIndirectSymbol(GV))
3769 Result = DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), Result,
3771 return Result;
3772}
3773
3774SDValue ARMTargetLowering::LowerGlobalAddressWindows(SDValue Op,
3775 SelectionDAG &DAG) const {
3776 assert(getTargetMachine().getTargetTriple().isOSWindows() &&
3777 "non-Windows COFF is not supported");
3778 assert(Subtarget->useMovt() &&
3779 "Windows on ARM expects to use movw/movt");
3780 assert(!Subtarget->isROPI() && !Subtarget->isRWPI() &&
3781 "ROPI/RWPI not currently supported for Windows");
3782
3783 const TargetMachine &TM = getTargetMachine();
3784 const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
3785 ARMII::TOF TargetFlags = ARMII::MO_NO_FLAG;
3786 if (GV->hasDLLImportStorageClass())
3787 TargetFlags = ARMII::MO_DLLIMPORT;
3788 else if (!TM.shouldAssumeDSOLocal(GV))
3789 TargetFlags = ARMII::MO_COFFSTUB;
3790 EVT PtrVT = getPointerTy(DAG.getDataLayout());
3791 SDValue Result;
3792 SDLoc DL(Op);
3793
3794 ++NumMovwMovt;
3795
3796 // FIXME: Once remat is capable of dealing with instructions with register
3797 // operands, expand this into two nodes.
3798 Result = DAG.getNode(ARMISD::Wrapper, DL, PtrVT,
3799 DAG.getTargetGlobalAddress(GV, DL, PtrVT, /*offset=*/0,
3800 TargetFlags));
3801 if (TargetFlags & (ARMII::MO_DLLIMPORT | ARMII::MO_COFFSTUB))
3802 Result = DAG.getLoad(PtrVT, DL, DAG.getEntryNode(), Result,
3804 return Result;
3805}
3806
3807SDValue
3808ARMTargetLowering::LowerEH_SJLJ_SETJMP(SDValue Op, SelectionDAG &DAG) const {
3809 SDLoc dl(Op);
3810 SDValue Val = DAG.getConstant(0, dl, MVT::i32);
3811 return DAG.getNode(ARMISD::EH_SJLJ_SETJMP, dl,
3812 DAG.getVTList(MVT::i32, MVT::Other), Op.getOperand(0),
3813 Op.getOperand(1), Val);
3814}
3815
3816SDValue
3817ARMTargetLowering::LowerEH_SJLJ_LONGJMP(SDValue Op, SelectionDAG &DAG) const {
3818 SDLoc dl(Op);
3819 return DAG.getNode(ARMISD::EH_SJLJ_LONGJMP, dl, MVT::Other, Op.getOperand(0),
3820 Op.getOperand(1), DAG.getConstant(0, dl, MVT::i32));
3821}
3822
3823SDValue ARMTargetLowering::LowerEH_SJLJ_SETUP_DISPATCH(SDValue Op,
3824 SelectionDAG &DAG) const {
3825 SDLoc dl(Op);
3826 return DAG.getNode(ARMISD::EH_SJLJ_SETUP_DISPATCH, dl, MVT::Other,
3827 Op.getOperand(0));
3828}
3829
3830SDValue ARMTargetLowering::LowerINTRINSIC_VOID(
3831 SDValue Op, SelectionDAG &DAG, const ARMSubtarget *Subtarget) const {
3832 unsigned IntNo =
3833 Op.getConstantOperandVal(Op.getOperand(0).getValueType() == MVT::Other);
3834 switch (IntNo) {
3835 default:
3836 return SDValue(); // Don't custom lower most intrinsics.
3837 case Intrinsic::arm_gnu_eabi_mcount: {
3839 EVT PtrVT = getPointerTy(DAG.getDataLayout());
3840 SDLoc dl(Op);
3841 SDValue Chain = Op.getOperand(0);
3842 // call "\01__gnu_mcount_nc"
3843 const ARMBaseRegisterInfo *ARI = Subtarget->getRegisterInfo();
3844 const uint32_t *Mask =
3846 assert(Mask && "Missing call preserved mask for calling convention");
3847 // Mark LR an implicit live-in.
3848 Register Reg = MF.addLiveIn(ARM::LR, getRegClassFor(MVT::i32));
3849 SDValue ReturnAddress =
3850 DAG.getCopyFromReg(DAG.getEntryNode(), dl, Reg, PtrVT);
3851 constexpr EVT ResultTys[] = {MVT::Other, MVT::Glue};
3852 SDValue Callee =
3853 DAG.getTargetExternalSymbol("\01__gnu_mcount_nc", PtrVT, 0);
3854 SDValue RegisterMask = DAG.getRegisterMask(Mask);
3855 if (Subtarget->isThumb())
3856 return SDValue(
3857 DAG.getMachineNode(
3858 ARM::tBL_PUSHLR, dl, ResultTys,
3859 {ReturnAddress, DAG.getTargetConstant(ARMCC::AL, dl, PtrVT),
3860 DAG.getRegister(0, PtrVT), Callee, RegisterMask, Chain}),
3861 0);
3862 return SDValue(
3863 DAG.getMachineNode(ARM::BL_PUSHLR, dl, ResultTys,
3864 {ReturnAddress, Callee, RegisterMask, Chain}),
3865 0);
3866 }
3867 }
3868}
3869
3870SDValue
3871ARMTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG,
3872 const ARMSubtarget *Subtarget) const {
3873 unsigned IntNo = Op.getConstantOperandVal(0);
3874 SDLoc dl(Op);
3875 switch (IntNo) {
3876 default: return SDValue(); // Don't custom lower most intrinsics.
3877 case Intrinsic::localaddress: {
3878 const MachineFunction &MF = DAG.getMachineFunction();
3879 const auto *RegInfo = Subtarget->getRegisterInfo();
3880 unsigned Reg = RegInfo->getLocalAddressRegister(MF);
3881 return DAG.getCopyFromReg(DAG.getEntryNode(), dl, Reg,
3882 Op.getSimpleValueType());
3883 }
3884 case Intrinsic::eh_recoverfp: {
3885 SDValue FnOp = Op.getOperand(1);
3886 GlobalAddressSDNode *GSD = dyn_cast<GlobalAddressSDNode>(FnOp);
3887 auto *Fn = dyn_cast_or_null<Function>(GSD ? GSD->getGlobal() : nullptr);
3888 if (!Fn)
3890 "llvm.eh.recoverfp must take a function as the first argument");
3891 const auto *RegInfo = Subtarget->getRegisterInfo();
3892 Register BaseReg = RegInfo->getBaseRegister();
3894 MachineBasicBlock &MBB = *MF.begin();
3895 if (!MBB.isLiveIn(BaseReg))
3896 MBB.addLiveIn(BaseReg);
3897 EVT PtrVT = getPointerTy(DAG.getDataLayout());
3898 return DAG.getCopyFromReg(DAG.getEntryNode(), dl, BaseReg, PtrVT);
3899 }
3900 case Intrinsic::thread_pointer: {
3901 EVT PtrVT = getPointerTy(DAG.getDataLayout());
3902 return DAG.getNode(ARMISD::THREAD_POINTER, dl, PtrVT);
3903 }
3904 case Intrinsic::arm_cls: {
3905 // Note: arm_cls and arm_cls64 intrinsics are expanded directly here
3906 // in LowerINTRINSIC_WO_CHAIN since there's no native scalar CLS
3907 // instruction.
3908 const SDValue &Operand = Op.getOperand(1);
3909 const EVT VTy = Op.getValueType();
3910 return DAG.getNode(ISD::CTLS, dl, VTy, Operand);
3911 }
3912 case Intrinsic::arm_cls64: {
3913 // arm_cls64 returns i32 but takes i64 input.
3914 // Use ISD::CTLS for i64 and truncate the result.
3915 SDValue CTLS64 = DAG.getNode(ISD::CTLS, dl, MVT::i64, Op.getOperand(1));
3916 return DAG.getNode(ISD::TRUNCATE, dl, MVT::i32, CTLS64);
3917 }
3918 case Intrinsic::arm_neon_vcls:
3919 case Intrinsic::arm_mve_vcls: {
3920 // Lower vector CLS intrinsics to ISD::CTLS.
3921 // Vector CTLS is Legal when NEON/MVE is available (set elsewhere).
3922 const EVT VTy = Op.getValueType();
3923 return DAG.getNode(ISD::CTLS, dl, VTy, Op.getOperand(1));
3924 }
3925 case Intrinsic::eh_sjlj_lsda: {
3927 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
3928 unsigned ARMPCLabelIndex = AFI->createPICLabelUId();
3929 EVT PtrVT = getPointerTy(DAG.getDataLayout());
3930 SDValue CPAddr;
3931 bool IsPositionIndependent = isPositionIndependent();
3932 unsigned PCAdj = IsPositionIndependent ? (Subtarget->isThumb() ? 4 : 8) : 0;
3933 ARMConstantPoolValue *CPV =
3934 ARMConstantPoolConstant::Create(&MF.getFunction(), ARMPCLabelIndex,
3935 ARMCP::CPLSDA, PCAdj);
3936 CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, Align(4));
3937 CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr);
3938 SDValue Result = DAG.getLoad(
3939 PtrVT, dl, DAG.getEntryNode(), CPAddr,
3941
3942 if (IsPositionIndependent) {
3943 SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, dl, MVT::i32);
3944 Result = DAG.getNode(ARMISD::PIC_ADD, dl, PtrVT, Result, PICLabel);
3945 }
3946 return Result;
3947 }
3948 case Intrinsic::arm_neon_vabs:
3949 return DAG.getNode(ISD::ABS, SDLoc(Op), Op.getValueType(),
3950 Op.getOperand(1));
3951 case Intrinsic::arm_neon_vabds:
3952 if (Op.getValueType().isInteger())
3953 return DAG.getNode(ISD::ABDS, SDLoc(Op), Op.getValueType(),
3954 Op.getOperand(1), Op.getOperand(2));
3955 return SDValue();
3956 case Intrinsic::arm_neon_vabdu:
3957 return DAG.getNode(ISD::ABDU, SDLoc(Op), Op.getValueType(),
3958 Op.getOperand(1), Op.getOperand(2));
3959 case Intrinsic::arm_neon_vmulls:
3960 case Intrinsic::arm_neon_vmullu: {
3961 unsigned NewOpc = (IntNo == Intrinsic::arm_neon_vmulls)
3962 ? ARMISD::VMULLs : ARMISD::VMULLu;
3963 return DAG.getNode(NewOpc, SDLoc(Op), Op.getValueType(),
3964 Op.getOperand(1), Op.getOperand(2));
3965 }
3966 case Intrinsic::arm_neon_vminnm:
3967 case Intrinsic::arm_neon_vmaxnm: {
3968 unsigned NewOpc = (IntNo == Intrinsic::arm_neon_vminnm)
3969 ? ISD::FMINNUM : ISD::FMAXNUM;
3970 return DAG.getNode(NewOpc, SDLoc(Op), Op.getValueType(),
3971 Op.getOperand(1), Op.getOperand(2));
3972 }
3973 case Intrinsic::arm_neon_vminu:
3974 case Intrinsic::arm_neon_vmaxu: {
3975 if (Op.getValueType().isFloatingPoint())
3976 return SDValue();
3977 unsigned NewOpc = (IntNo == Intrinsic::arm_neon_vminu)
3978 ? ISD::UMIN : ISD::UMAX;
3979 return DAG.getNode(NewOpc, SDLoc(Op), Op.getValueType(),
3980 Op.getOperand(1), Op.getOperand(2));
3981 }
3982 case Intrinsic::arm_neon_vmins:
3983 case Intrinsic::arm_neon_vmaxs: {
3984 // v{min,max}s is overloaded between signed integers and floats.
3985 if (!Op.getValueType().isFloatingPoint()) {
3986 unsigned NewOpc = (IntNo == Intrinsic::arm_neon_vmins)
3987 ? ISD::SMIN : ISD::SMAX;
3988 return DAG.getNode(NewOpc, SDLoc(Op), Op.getValueType(),
3989 Op.getOperand(1), Op.getOperand(2));
3990 }
3991 unsigned NewOpc = (IntNo == Intrinsic::arm_neon_vmins)
3992 ? ISD::FMINIMUM : ISD::FMAXIMUM;
3993 return DAG.getNode(NewOpc, SDLoc(Op), Op.getValueType(),
3994 Op.getOperand(1), Op.getOperand(2));
3995 }
3996 case Intrinsic::arm_neon_vtbl1:
3997 return DAG.getNode(ARMISD::VTBL1, SDLoc(Op), Op.getValueType(),
3998 Op.getOperand(1), Op.getOperand(2));
3999 case Intrinsic::arm_neon_vtbl2:
4000 return DAG.getNode(ARMISD::VTBL2, SDLoc(Op), Op.getValueType(),
4001 Op.getOperand(1), Op.getOperand(2), Op.getOperand(3));
4002 case Intrinsic::arm_mve_pred_i2v:
4003 case Intrinsic::arm_mve_pred_v2i:
4004 return DAG.getNode(ARMISD::PREDICATE_CAST, SDLoc(Op), Op.getValueType(),
4005 Op.getOperand(1));
4006 case Intrinsic::arm_mve_vreinterpretq:
4007 return DAG.getNode(ARMISD::VECTOR_REG_CAST, SDLoc(Op), Op.getValueType(),
4008 Op.getOperand(1));
4009 case Intrinsic::arm_mve_lsll:
4010 return DAG.getNode(ARMISD::LSLL, SDLoc(Op), Op->getVTList(),
4011 Op.getOperand(1), Op.getOperand(2), Op.getOperand(3));
4012 case Intrinsic::arm_mve_asrl:
4013 return DAG.getNode(ARMISD::ASRL, SDLoc(Op), Op->getVTList(),
4014 Op.getOperand(1), Op.getOperand(2), Op.getOperand(3));
4015 case Intrinsic::arm_mve_vsli:
4016 return DAG.getNode(ARMISD::VSLIIMM, SDLoc(Op), Op->getVTList(),
4017 Op.getOperand(1), Op.getOperand(2), Op.getOperand(3));
4018 case Intrinsic::arm_mve_vsri:
4019 return DAG.getNode(ARMISD::VSRIIMM, SDLoc(Op), Op->getVTList(),
4020 Op.getOperand(1), Op.getOperand(2), Op.getOperand(3));
4021 }
4022}
4023
4025 const ARMSubtarget *Subtarget) {
4026 SDLoc dl(Op);
4027 auto SSID = static_cast<SyncScope::ID>(Op.getConstantOperandVal(2));
4028 if (SSID == SyncScope::SingleThread)
4029 return Op;
4030
4031 if (!Subtarget->hasDataBarrier()) {
4032 // Some ARMv6 cpus can support data barriers with an mcr instruction.
4033 // Thumb1 and pre-v6 ARM mode use a libcall instead and should never get
4034 // here.
4035 assert(Subtarget->hasV6Ops() && !Subtarget->isThumb() &&
4036 "Unexpected ISD::ATOMIC_FENCE encountered. Should be libcall!");
4037 return DAG.getNode(ARMISD::MEMBARRIER_MCR, dl, MVT::Other, Op.getOperand(0),
4038 DAG.getConstant(0, dl, MVT::i32));
4039 }
4040
4041 AtomicOrdering Ord =
4042 static_cast<AtomicOrdering>(Op.getConstantOperandVal(1));
4044 if (Subtarget->isMClass()) {
4045 // Only a full system barrier exists in the M-class architectures.
4047 } else if (Subtarget->preferISHSTBarriers() &&
4048 Ord == AtomicOrdering::Release) {
4049 // Swift happens to implement ISHST barriers in a way that's compatible with
4050 // Release semantics but weaker than ISH so we'd be fools not to use
4051 // it. Beware: other processors probably don't!
4053 }
4054
4055 return DAG.getNode(ISD::INTRINSIC_VOID, dl, MVT::Other, Op.getOperand(0),
4056 DAG.getConstant(Intrinsic::arm_dmb, dl, MVT::i32),
4057 DAG.getConstant(Domain, dl, MVT::i32));
4058}
4059
4061 const ARMSubtarget *Subtarget) {
4062 // ARM pre v5TE and Thumb1 does not have preload instructions.
4063 if (!(Subtarget->isThumb2() ||
4064 (!Subtarget->isThumb1Only() && Subtarget->hasV5TEOps())))
4065 // Just preserve the chain.
4066 return Op.getOperand(0);
4067
4068 SDLoc dl(Op);
4069 unsigned isRead = ~Op.getConstantOperandVal(2) & 1;
4070 if (!isRead &&
4071 (!Subtarget->hasV7Ops() || !Subtarget->hasMPExtension()))
4072 // ARMv7 with MP extension has PLDW.
4073 return Op.getOperand(0);
4074
4075 unsigned isData = Op.getConstantOperandVal(4);
4076 if (Subtarget->isThumb()) {
4077 // Invert the bits.
4078 isRead = ~isRead & 1;
4079 isData = ~isData & 1;
4080 }
4081
4082 return DAG.getNode(ARMISD::PRELOAD, dl, MVT::Other, Op.getOperand(0),
4083 Op.getOperand(1), DAG.getConstant(isRead, dl, MVT::i32),
4084 DAG.getConstant(isData, dl, MVT::i32));
4085}
4086
4089 ARMFunctionInfo *FuncInfo = MF.getInfo<ARMFunctionInfo>();
4090
4091 // vastart just stores the address of the VarArgsFrameIndex slot into the
4092 // memory location argument.
4093 SDLoc dl(Op);
4095 SDValue FR = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(), PtrVT);
4096 const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
4097 return DAG.getStore(Op.getOperand(0), dl, FR, Op.getOperand(1),
4098 MachinePointerInfo(SV));
4099}
4100
4101SDValue ARMTargetLowering::GetF64FormalArgument(CCValAssign &VA,
4102 CCValAssign &NextVA,
4103 SDValue &Root,
4104 SelectionDAG &DAG,
4105 const SDLoc &dl) const {
4107 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
4108
4109 const TargetRegisterClass *RC;
4110 if (AFI->isThumb1OnlyFunction())
4111 RC = &ARM::tGPRRegClass;
4112 else
4113 RC = &ARM::GPRRegClass;
4114
4115 // Transform the arguments stored in physical registers into virtual ones.
4116 Register Reg = MF.addLiveIn(VA.getLocReg(), RC);
4117 SDValue ArgValue = DAG.getCopyFromReg(Root, dl, Reg, MVT::i32);
4118
4119 SDValue ArgValue2;
4120 if (NextVA.isMemLoc()) {
4121 MachineFrameInfo &MFI = MF.getFrameInfo();
4122 int FI = MFI.CreateFixedObject(4, NextVA.getLocMemOffset(), true);
4123
4124 // Create load node to retrieve arguments from the stack.
4125 SDValue FIN = DAG.getFrameIndex(FI, getPointerTy(DAG.getDataLayout()));
4126 ArgValue2 = DAG.getLoad(
4127 MVT::i32, dl, Root, FIN,
4129 } else {
4130 Reg = MF.addLiveIn(NextVA.getLocReg(), RC);
4131 ArgValue2 = DAG.getCopyFromReg(Root, dl, Reg, MVT::i32);
4132 }
4133 if (!Subtarget->isLittle())
4134 std::swap (ArgValue, ArgValue2);
4135 return DAG.getNode(ARMISD::VMOVDRR, dl, MVT::f64, ArgValue, ArgValue2);
4136}
4137
4138// The remaining GPRs hold either the beginning of variable-argument
4139// data, or the beginning of an aggregate passed by value (usually
4140// byval). Either way, we allocate stack slots adjacent to the data
4141// provided by our caller, and store the unallocated registers there.
4142// If this is a variadic function, the va_list pointer will begin with
4143// these values; otherwise, this reassembles a (byval) structure that
4144// was split between registers and memory.
4145// Return: The frame index registers were stored into.
4146int ARMTargetLowering::StoreByValRegs(CCState &CCInfo, SelectionDAG &DAG,
4147 const SDLoc &dl, SDValue &Chain,
4148 const Value *OrigArg,
4149 unsigned InRegsParamRecordIdx,
4150 int ArgOffset, unsigned ArgSize) const {
4151 // Currently, two use-cases possible:
4152 // Case #1. Non-var-args function, and we meet first byval parameter.
4153 // Setup first unallocated register as first byval register;
4154 // eat all remained registers
4155 // (these two actions are performed by HandleByVal method).
4156 // Then, here, we initialize stack frame with
4157 // "store-reg" instructions.
4158 // Case #2. Var-args function, that doesn't contain byval parameters.
4159 // The same: eat all remained unallocated registers,
4160 // initialize stack frame.
4161
4163 MachineFrameInfo &MFI = MF.getFrameInfo();
4164 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
4165 unsigned RBegin, REnd;
4166 if (InRegsParamRecordIdx < CCInfo.getInRegsParamsCount()) {
4167 CCInfo.getInRegsParamInfo(InRegsParamRecordIdx, RBegin, REnd);
4168 } else {
4169 unsigned RBeginIdx = CCInfo.getFirstUnallocated(GPRArgRegs);
4170 RBegin = RBeginIdx == 4 ? (unsigned)ARM::R4 : GPRArgRegs[RBeginIdx];
4171 REnd = ARM::R4;
4172 }
4173
4174 if (REnd != RBegin)
4175 ArgOffset = -4 * (ARM::R4 - RBegin);
4176
4177 auto PtrVT = getPointerTy(DAG.getDataLayout());
4178 int FrameIndex = MFI.CreateFixedObject(ArgSize, ArgOffset, false);
4179 SDValue FIN = DAG.getFrameIndex(FrameIndex, PtrVT);
4180
4182 const TargetRegisterClass *RC =
4183 AFI->isThumb1OnlyFunction() ? &ARM::tGPRRegClass : &ARM::GPRRegClass;
4184
4185 for (unsigned Reg = RBegin, i = 0; Reg < REnd; ++Reg, ++i) {
4186 Register VReg = MF.addLiveIn(Reg, RC);
4187 SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, MVT::i32);
4188 SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN,
4189 MachinePointerInfo(OrigArg, 4 * i));
4190 MemOps.push_back(Store);
4191 FIN = DAG.getNode(ISD::ADD, dl, PtrVT, FIN, DAG.getConstant(4, dl, PtrVT));
4192 }
4193
4194 if (!MemOps.empty())
4195 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOps);
4196 return FrameIndex;
4197}
4198
4199// Setup stack frame, the va_list pointer will start from.
4200void ARMTargetLowering::VarArgStyleRegisters(CCState &CCInfo, SelectionDAG &DAG,
4201 const SDLoc &dl, SDValue &Chain,
4202 unsigned ArgOffset,
4203 unsigned TotalArgRegsSaveSize,
4204 bool ForceMutable) const {
4206 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
4207
4208 // Try to store any remaining integer argument regs
4209 // to their spots on the stack so that they may be loaded by dereferencing
4210 // the result of va_next.
4211 // If there is no regs to be stored, just point address after last
4212 // argument passed via stack.
4213 int FrameIndex = StoreByValRegs(
4214 CCInfo, DAG, dl, Chain, nullptr, CCInfo.getInRegsParamsCount(),
4215 CCInfo.getStackSize(), std::max(4U, TotalArgRegsSaveSize));
4216 AFI->setVarArgsFrameIndex(FrameIndex);
4217}
4218
4219bool ARMTargetLowering::splitValueIntoRegisterParts(
4220 SelectionDAG &DAG, const SDLoc &DL, SDValue Val, SDValue *Parts,
4221 unsigned NumParts, MVT PartVT, std::optional<CallingConv::ID> CC) const {
4222 EVT ValueVT = Val.getValueType();
4223 if ((ValueVT == MVT::f16 || ValueVT == MVT::bf16) && PartVT == MVT::f32) {
4224 unsigned ValueBits = ValueVT.getSizeInBits();
4225 unsigned PartBits = PartVT.getSizeInBits();
4226 Val = DAG.getNode(ISD::BITCAST, DL, MVT::getIntegerVT(ValueBits), Val);
4227 Val = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::getIntegerVT(PartBits), Val);
4228 Val = DAG.getNode(ISD::BITCAST, DL, PartVT, Val);
4229 Parts[0] = Val;
4230 return true;
4231 }
4232 return false;
4233}
4234
4235SDValue ARMTargetLowering::joinRegisterPartsIntoValue(
4236 SelectionDAG &DAG, const SDLoc &DL, const SDValue *Parts, unsigned NumParts,
4237 MVT PartVT, EVT ValueVT, std::optional<CallingConv::ID> CC) const {
4238 if ((ValueVT == MVT::f16 || ValueVT == MVT::bf16) && PartVT == MVT::f32) {
4239 unsigned ValueBits = ValueVT.getSizeInBits();
4240 unsigned PartBits = PartVT.getSizeInBits();
4241 SDValue Val = Parts[0];
4242
4243 Val = DAG.getNode(ISD::BITCAST, DL, MVT::getIntegerVT(PartBits), Val);
4244 Val = DAG.getNode(ISD::TRUNCATE, DL, MVT::getIntegerVT(ValueBits), Val);
4245 Val = DAG.getNode(ISD::BITCAST, DL, ValueVT, Val);
4246 return Val;
4247 }
4248 return SDValue();
4249}
4250
4251SDValue ARMTargetLowering::LowerFormalArguments(
4252 SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
4253 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
4254 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
4256 MachineFrameInfo &MFI = MF.getFrameInfo();
4257
4258 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
4259
4260 // Assign locations to all of the incoming arguments.
4262 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), ArgLocs,
4263 *DAG.getContext());
4264 CCInfo.AnalyzeFormalArguments(Ins, CCAssignFnForCall(CallConv, isVarArg));
4265
4267 unsigned CurArgIdx = 0;
4268
4269 // Initially ArgRegsSaveSize is zero.
4270 // Then we increase this value each time we meet byval parameter.
4271 // We also increase this value in case of varargs function.
4272 AFI->setArgRegsSaveSize(0);
4273
4274 // Calculate the amount of stack space that we need to allocate to store
4275 // byval and variadic arguments that are passed in registers.
4276 // We need to know this before we allocate the first byval or variadic
4277 // argument, as they will be allocated a stack slot below the CFA (Canonical
4278 // Frame Address, the stack pointer at entry to the function).
4279 unsigned ArgRegBegin = ARM::R4;
4280 for (const CCValAssign &VA : ArgLocs) {
4281 if (CCInfo.getInRegsParamsProcessed() >= CCInfo.getInRegsParamsCount())
4282 break;
4283
4284 unsigned Index = VA.getValNo();
4285 ISD::ArgFlagsTy Flags = Ins[Index].Flags;
4286 if (!Flags.isByVal())
4287 continue;
4288
4289 assert(VA.isMemLoc() && "unexpected byval pointer in reg");
4290 unsigned RBegin, REnd;
4291 CCInfo.getInRegsParamInfo(CCInfo.getInRegsParamsProcessed(), RBegin, REnd);
4292 ArgRegBegin = std::min(ArgRegBegin, RBegin);
4293
4294 CCInfo.nextInRegsParam();
4295 }
4296 CCInfo.rewindByValRegsInfo();
4297
4298 int lastInsIndex = -1;
4299 if (isVarArg && MFI.hasVAStart()) {
4300 unsigned RegIdx = CCInfo.getFirstUnallocated(GPRArgRegs);
4301 if (RegIdx != std::size(GPRArgRegs))
4302 ArgRegBegin = std::min(ArgRegBegin, (unsigned)GPRArgRegs[RegIdx]);
4303 }
4304
4305 unsigned TotalArgRegsSaveSize = 4 * (ARM::R4 - ArgRegBegin);
4306 AFI->setArgRegsSaveSize(TotalArgRegsSaveSize);
4307 auto PtrVT = getPointerTy(DAG.getDataLayout());
4308
4309 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
4310 CCValAssign &VA = ArgLocs[i];
4311 if (Ins[VA.getValNo()].isOrigArg()) {
4312 std::advance(CurOrigArg,
4313 Ins[VA.getValNo()].getOrigArgIndex() - CurArgIdx);
4314 CurArgIdx = Ins[VA.getValNo()].getOrigArgIndex();
4315 }
4316 // Arguments stored in registers.
4317 if (VA.isRegLoc()) {
4318 EVT RegVT = VA.getLocVT();
4319 SDValue ArgValue;
4320
4321 if (VA.needsCustom() && VA.getLocVT() == MVT::v2f64) {
4322 // f64 and vector types are split up into multiple registers or
4323 // combinations of registers and stack slots.
4324 SDValue ArgValue1 =
4325 GetF64FormalArgument(VA, ArgLocs[++i], Chain, DAG, dl);
4326 VA = ArgLocs[++i]; // skip ahead to next loc
4327 SDValue ArgValue2;
4328 if (VA.isMemLoc()) {
4329 int FI = MFI.CreateFixedObject(8, VA.getLocMemOffset(), true);
4330 SDValue FIN = DAG.getFrameIndex(FI, PtrVT);
4331 ArgValue2 = DAG.getLoad(
4332 MVT::f64, dl, Chain, FIN,
4334 } else {
4335 ArgValue2 = GetF64FormalArgument(VA, ArgLocs[++i], Chain, DAG, dl);
4336 }
4337 ArgValue = DAG.getNode(ISD::UNDEF, dl, MVT::v2f64);
4338 ArgValue = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, MVT::v2f64, ArgValue,
4339 ArgValue1, DAG.getIntPtrConstant(0, dl));
4340 ArgValue = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, MVT::v2f64, ArgValue,
4341 ArgValue2, DAG.getIntPtrConstant(1, dl));
4342 } else if (VA.needsCustom() && VA.getLocVT() == MVT::f64) {
4343 ArgValue = GetF64FormalArgument(VA, ArgLocs[++i], Chain, DAG, dl);
4344 } else {
4345 const TargetRegisterClass *RC;
4346
4347 if (RegVT == MVT::f16 || RegVT == MVT::bf16)
4348 RC = &ARM::HPRRegClass;
4349 else if (RegVT == MVT::f32)
4350 RC = &ARM::SPRRegClass;
4351 else if (RegVT == MVT::f64 || RegVT == MVT::v4f16 ||
4352 RegVT == MVT::v4bf16)
4353 RC = &ARM::DPRRegClass;
4354 else if (RegVT == MVT::v2f64 || RegVT == MVT::v8f16 ||
4355 RegVT == MVT::v8bf16)
4356 RC = &ARM::QPRRegClass;
4357 else if (RegVT == MVT::i32)
4358 RC = AFI->isThumb1OnlyFunction() ? &ARM::tGPRRegClass
4359 : &ARM::GPRRegClass;
4360 else
4361 llvm_unreachable("RegVT not supported by FORMAL_ARGUMENTS Lowering");
4362
4363 // Transform the arguments in physical registers into virtual ones.
4364 Register Reg = MF.addLiveIn(VA.getLocReg(), RC);
4365 ArgValue = DAG.getCopyFromReg(Chain, dl, Reg, RegVT);
4366
4367 // If this value is passed in r0 and has the returned attribute (e.g.
4368 // C++ 'structors), record this fact for later use.
4369 if (VA.getLocReg() == ARM::R0 && Ins[VA.getValNo()].Flags.isReturned()) {
4370 AFI->setPreservesR0();
4371 }
4372 }
4373
4374 // If this is an 8 or 16-bit value, it is really passed promoted
4375 // to 32 bits. Insert an assert[sz]ext to capture this, then
4376 // truncate to the right size.
4377 switch (VA.getLocInfo()) {
4378 default: llvm_unreachable("Unknown loc info!");
4379 case CCValAssign::Full: break;
4380 case CCValAssign::BCvt:
4381 ArgValue = DAG.getNode(ISD::BITCAST, dl, VA.getValVT(), ArgValue);
4382 break;
4383 }
4384
4385 // f16 arguments have their size extended to 4 bytes and passed as if they
4386 // had been copied to the LSBs of a 32-bit register.
4387 // For that, it's passed extended to i32 (soft ABI) or to f32 (hard ABI)
4388 if (VA.needsCustom() &&
4389 (VA.getValVT() == MVT::f16 || VA.getValVT() == MVT::bf16))
4390 ArgValue = MoveToHPR(dl, DAG, VA.getLocVT(), VA.getValVT(), ArgValue);
4391
4392 // On CMSE Entry Functions, formal integer arguments whose bitwidth is
4393 // less than 32 bits must be sign- or zero-extended in the callee for
4394 // security reasons. Although the ABI mandates an extension done by the
4395 // caller, the latter cannot be trusted to follow the rules of the ABI.
4396 const ISD::InputArg &Arg = Ins[VA.getValNo()];
4397 if (AFI->isCmseNSEntryFunction() && Arg.ArgVT.isScalarInteger() &&
4398 RegVT.isScalarInteger() && Arg.ArgVT.bitsLT(MVT::i32))
4399 ArgValue = handleCMSEValue(ArgValue, Arg, DAG, dl);
4400
4401 InVals.push_back(ArgValue);
4402 } else { // VA.isRegLoc()
4403 // Only arguments passed on the stack should make it here.
4404 assert(VA.isMemLoc());
4405 assert(VA.getValVT() != MVT::i64 && "i64 should already be lowered");
4406
4407 int index = VA.getValNo();
4408
4409 // Some Ins[] entries become multiple ArgLoc[] entries.
4410 // Process them only once.
4411 if (index != lastInsIndex)
4412 {
4413 ISD::ArgFlagsTy Flags = Ins[index].Flags;
4414 // FIXME: For now, all byval parameter objects are marked mutable.
4415 // This can be changed with more analysis.
4416 // In case of tail call optimization mark all arguments mutable.
4417 // Since they could be overwritten by lowering of arguments in case of
4418 // a tail call.
4419 if (Flags.isByVal()) {
4420 assert(Ins[index].isOrigArg() &&
4421 "Byval arguments cannot be implicit");
4422 unsigned CurByValIndex = CCInfo.getInRegsParamsProcessed();
4423
4424 int FrameIndex = StoreByValRegs(
4425 CCInfo, DAG, dl, Chain, &*CurOrigArg, CurByValIndex,
4426 VA.getLocMemOffset(), Flags.getByValSize());
4427 InVals.push_back(DAG.getFrameIndex(FrameIndex, PtrVT));
4428 CCInfo.nextInRegsParam();
4429 } else if (VA.needsCustom() && (VA.getValVT() == MVT::f16 ||
4430 VA.getValVT() == MVT::bf16)) {
4431 // f16 and bf16 values are passed in the least-significant half of
4432 // a 4 byte stack slot. This is done as-if the extension was done
4433 // in a 32-bit register, so the actual bytes used for the value
4434 // differ between little and big endian.
4435 assert(VA.getLocVT().getSizeInBits() == 32);
4436 unsigned FIOffset = VA.getLocMemOffset();
4437 int FI = MFI.CreateFixedObject(VA.getLocVT().getSizeInBits() / 8,
4438 FIOffset, true);
4439
4440 SDValue Addr = DAG.getFrameIndex(FI, PtrVT);
4441 if (DAG.getDataLayout().isBigEndian())
4442 Addr = DAG.getObjectPtrOffset(dl, Addr, TypeSize::getFixed(2));
4443
4444 InVals.push_back(DAG.getLoad(VA.getValVT(), dl, Chain, Addr,
4446 DAG.getMachineFunction(), FI)));
4447
4448 } else {
4449 unsigned FIOffset = VA.getLocMemOffset();
4450 int FI = MFI.CreateFixedObject(VA.getLocVT().getSizeInBits()/8,
4451 FIOffset, true);
4452
4453 // Create load nodes to retrieve arguments from the stack.
4454 SDValue FIN = DAG.getFrameIndex(FI, PtrVT);
4455 InVals.push_back(DAG.getLoad(VA.getValVT(), dl, Chain, FIN,
4457 DAG.getMachineFunction(), FI)));
4458 }
4459 lastInsIndex = index;
4460 }
4461 }
4462 }
4463
4464 // varargs
4465 if (isVarArg && MFI.hasVAStart()) {
4466 VarArgStyleRegisters(CCInfo, DAG, dl, Chain, CCInfo.getStackSize(),
4467 TotalArgRegsSaveSize);
4468 if (AFI->isCmseNSEntryFunction()) {
4469 DAG.getContext()->diagnose(DiagnosticInfoUnsupported(
4471 "secure entry function must not be variadic", dl.getDebugLoc()));
4472 }
4473 }
4474
4475 unsigned StackArgSize = CCInfo.getStackSize();
4476 bool TailCallOpt = MF.getTarget().Options.GuaranteedTailCallOpt;
4477 if (canGuaranteeTCO(CallConv, TailCallOpt)) {
4478 // The only way to guarantee a tail call is if the callee restores its
4479 // argument area, but it must also keep the stack aligned when doing so.
4480 MaybeAlign StackAlign = DAG.getDataLayout().getStackAlignment();
4481 assert(StackAlign && "data layout string is missing stack alignment");
4482 StackArgSize = alignTo(StackArgSize, *StackAlign);
4483
4484 AFI->setArgumentStackToRestore(StackArgSize);
4485 }
4486 AFI->setArgumentStackSize(StackArgSize);
4487
4488 if (CCInfo.getStackSize() > 0 && AFI->isCmseNSEntryFunction()) {
4489 DAG.getContext()->diagnose(DiagnosticInfoUnsupported(
4491 "secure entry function requires arguments on stack", dl.getDebugLoc()));
4492 }
4493
4494 return Chain;
4495}
4496
4497/// isFloatingPointZero - Return true if this is +0.0.
4500 return CFP->getValueAPF().isPosZero();
4501 else if (ISD::isEXTLoad(Op.getNode()) || ISD::isNON_EXTLoad(Op.getNode())) {
4502 // Maybe this has already been legalized into the constant pool?
4503 if (Op.getOperand(1).getOpcode() == ARMISD::Wrapper) {
4504 SDValue WrapperOp = Op.getOperand(1).getOperand(0);
4506 if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CP->getConstVal()))
4507 return CFP->getValueAPF().isPosZero();
4508 }
4509 } else if (Op->getOpcode() == ISD::BITCAST &&
4510 Op->getValueType(0) == MVT::f64) {
4511 // Handle (ISD::BITCAST (ARMISD::VMOVIMM (ISD::TargetConstant 0)) MVT::f64)
4512 // created by LowerConstantFP().
4513 SDValue BitcastOp = Op->getOperand(0);
4514 if (BitcastOp->getOpcode() == ARMISD::VMOVIMM &&
4515 isNullConstant(BitcastOp->getOperand(0)))
4516 return true;
4517 }
4518 return false;
4519}
4520
4522 // 0 - INT_MIN sign wraps, so no signed wrap means cmn is safe.
4523 if (Op->getFlags().hasNoSignedWrap())
4524 return true;
4525
4526 // We can still figure out if the second operand is safe to use
4527 // in a CMN instruction by checking if it is known to be not the minimum
4528 // signed value. If it is not, then we can safely use CMN.
4529 // Note: We can eventually remove this check and simply rely on
4530 // Op->getFlags().hasNoSignedWrap() once SelectionDAG/ISelLowering
4531 // consistently sets them appropriately when making said nodes.
4532
4533 KnownBits KnownSrc = DAG.computeKnownBits(Op.getOperand(1));
4534 return !KnownSrc.getSignedMinValue().isMinSignedValue();
4535}
4536
4538 return Op.getOpcode() == ISD::SUB && isNullConstant(Op.getOperand(0)) &&
4539 (isIntEqualitySetCC(CC) ||
4540 (isUnsignedIntSetCC(CC) && DAG.isKnownNeverZero(Op.getOperand(1))) ||
4541 (isSignedIntSetCC(CC) && isSafeSignedCMN(Op, DAG)));
4542}
4543
4544/// Returns how profitable it is to fold a comparison's operand's shift and/or
4545/// extension operations into the comparison instruction's second operand
4546/// (so_reg_imm / so_reg_reg for ARM, t2_so_reg for Thumb-2).
4548 // Thumb-1 CMP does not support shifted second operands.
4549 if (ST.isThumb1Only() || !Op.hasOneUse())
4550 return 0;
4551
4552 unsigned Opc = Op.getOpcode();
4553 if (Opc == ISD::SHL || Opc == ISD::SRL || Opc == ISD::SRA) {
4554 if (auto *ShiftAmt = dyn_cast<ConstantSDNode>(Op.getOperand(1)))
4555 return ShiftAmt->getZExtValue() <= 31 ? 1 : 0;
4556 // Register-controlled shift: only ARM-mode CMP/CMN (so_reg_reg) supports
4557 // this; Thumb-2 t2_so_reg requires an immediate shift amount.
4558 return ST.isThumb() ? 0 : 1;
4559 }
4560
4561 if (Opc == ISD::ROTR) {
4562 // Rotr constants will be normalized via mod 32, or & 31,
4563 // so we do not have to bounds check.
4564 if (isa<ConstantSDNode>(Op.getOperand(1)))
4565 return 1;
4566 return ST.isThumb() ? 0 : 1;
4567 }
4568
4569 return 0;
4570}
4571
4572/// Returns appropriate ARM CMP (cmp) and corresponding condition code for
4573/// the given operands.
4574SDValue ARMTargetLowering::getARMCmp(SDValue LHS, SDValue RHS, ISD::CondCode CC,
4575 SDValue &ARMcc, SelectionDAG &DAG,
4576 const SDLoc &dl) const {
4577 if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(RHS.getNode())) {
4578 unsigned C = RHSC->getZExtValue();
4579 if (!isLegalICmpImmediate((int32_t)C)) {
4580 // Constant does not fit, try adjusting it by one.
4581 switch (CC) {
4582 default: break;
4583 case ISD::SETLT:
4584 case ISD::SETGE:
4585 if (C != 0x80000000 && isLegalICmpImmediate(C-1)) {
4586 CC = (CC == ISD::SETLT) ? ISD::SETLE : ISD::SETGT;
4587 RHS = DAG.getConstant(C - 1, dl, MVT::i32);
4588 }
4589 break;
4590 case ISD::SETULT:
4591 case ISD::SETUGE:
4592 if (C != 0 && isLegalICmpImmediate(C-1)) {
4593 CC = (CC == ISD::SETULT) ? ISD::SETULE : ISD::SETUGT;
4594 RHS = DAG.getConstant(C - 1, dl, MVT::i32);
4595 }
4596 break;
4597 case ISD::SETLE:
4598 case ISD::SETGT:
4599 if (C != 0x7fffffff && isLegalICmpImmediate(C+1)) {
4600 CC = (CC == ISD::SETLE) ? ISD::SETLT : ISD::SETGE;
4601 RHS = DAG.getConstant(C + 1, dl, MVT::i32);
4602 }
4603 break;
4604 case ISD::SETULE:
4605 case ISD::SETUGT:
4606 if (C != 0xffffffff && isLegalICmpImmediate(C+1)) {
4607 CC = (CC == ISD::SETULE) ? ISD::SETULT : ISD::SETUGE;
4608 RHS = DAG.getConstant(C + 1, dl, MVT::i32);
4609 }
4610 break;
4611 }
4612 }
4613 }
4614
4615 // Thumb1 has very limited immediate modes, so turning an "and" into a
4616 // shift can save multiple instructions.
4617 //
4618 // If we have (x & C1), and C1 is an appropriate mask, we can transform it
4619 // into "((x << n) >> n)". But that isn't necessarily profitable on its
4620 // own. If it's the operand to an unsigned comparison with an immediate,
4621 // we can eliminate one of the shifts: we transform
4622 // "((x << n) >> n) == C2" to "(x << n) == (C2 << n)".
4623 //
4624 // We avoid transforming cases which aren't profitable due to encoding
4625 // details:
4626 //
4627 // 1. C2 fits into the immediate field of a cmp, and the transformed version
4628 // would not; in that case, we're essentially trading one immediate load for
4629 // another.
4630 // 2. C1 is 255 or 65535, so we can use uxtb or uxth.
4631 // 3. C2 is zero; we have other code for this special case.
4632 //
4633 // FIXME: Figure out profitability for Thumb2; we usually can't save an
4634 // instruction, since the AND is always one instruction anyway, but we could
4635 // use narrow instructions in some cases.
4636 if (Subtarget->isThumb1Only() && LHS->getOpcode() == ISD::AND &&
4637 LHS->hasOneUse() && isa<ConstantSDNode>(LHS.getOperand(1)) &&
4638 LHS.getValueType() == MVT::i32 && isa<ConstantSDNode>(RHS) &&
4639 !isSignedIntSetCC(CC)) {
4640 unsigned Mask = LHS.getConstantOperandVal(1);
4641 auto *RHSC = cast<ConstantSDNode>(RHS.getNode());
4642 uint64_t RHSV = RHSC->getZExtValue();
4643 if (isMask_32(Mask) && (RHSV & ~Mask) == 0 && Mask != 255 && Mask != 65535) {
4644 unsigned ShiftBits = llvm::countl_zero(Mask);
4645 if (RHSV && (RHSV > 255 || (RHSV << ShiftBits) <= 255)) {
4646 SDValue ShiftAmt = DAG.getConstant(ShiftBits, dl, MVT::i32);
4647 LHS = DAG.getNode(ISD::SHL, dl, MVT::i32, LHS.getOperand(0), ShiftAmt);
4648 RHS = DAG.getConstant(RHSV << ShiftBits, dl, MVT::i32);
4649 }
4650 }
4651 }
4652
4653 // The specific comparison "(x<<c) > 0x80000000U" can be optimized to a
4654 // single "lsls x, c+1". The shift sets the "C" and "Z" flags the same
4655 // way a cmp would.
4656 // FIXME: Add support for ARM/Thumb2; this would need isel patterns, and
4657 // some tweaks to the heuristics for the previous and->shift transform.
4658 // FIXME: Optimize cases where the LHS isn't a shift.
4659 if (Subtarget->isThumb1Only() && LHS->getOpcode() == ISD::SHL &&
4660 isa<ConstantSDNode>(RHS) && RHS->getAsZExtVal() == 0x80000000U &&
4661 CC == ISD::SETUGT && isa<ConstantSDNode>(LHS.getOperand(1)) &&
4662 LHS.getConstantOperandVal(1) < 31) {
4663 unsigned ShiftAmt = LHS.getConstantOperandVal(1) + 1;
4664 SDValue Shift =
4665 DAG.getNode(ARMISD::LSLS, dl, DAG.getVTList(MVT::i32, FlagsVT),
4666 LHS.getOperand(0), DAG.getConstant(ShiftAmt, dl, MVT::i32));
4667 ARMcc = DAG.getConstant(ARMCC::HI, dl, MVT::i32);
4668 return Shift.getValue(1);
4669 }
4670
4672
4673 unsigned CompareType;
4674 switch (CondCode) {
4675 default:
4676 CompareType = ARMISD::CMP;
4677 break;
4678 case ARMCC::EQ:
4679 case ARMCC::NE:
4680 // Uses only Z Flag
4681 CompareType = ARMISD::CMPZ;
4682 break;
4683 }
4684
4685 // TODO: Remove CMPZ check once we generalize and remove the CMPZ enum from
4686 // the codebase.
4687
4688 // TODO: When we have a solution to the vselect predicate not allowing pl/mi
4689 // all the time, allow those cases to be cmn too no matter what.
4690 if (CompareType != ARMISD::CMPZ && isCMN(RHS, CC, DAG)) {
4691 CompareType = ARMISD::CMN;
4692 RHS = RHS.getOperand(1);
4693 } else if (CompareType != ARMISD::CMPZ && isCMN(LHS, CC, DAG)) {
4694 CompareType = ARMISD::CMN;
4695 LHS = LHS.getOperand(1);
4697 }
4698
4699 // Prefer folding shifts / CMN into the cmp/cmn second operand (so_reg /
4700 // t2_so_reg). When both sides compete, pick the higher
4701 // getCmpOperandFoldingProfit. Only when RHS is not a legal icmp
4702 // immediate: otherwise keep the canonical (reg, imm) form.
4703 ConstantSDNode *C = dyn_cast<ConstantSDNode>(RHS.getNode());
4704 if (!C || !isLegalICmpImmediate(C->getSExtValue())) {
4705 if (getCmpOperandFoldingProfit(LHS, *Subtarget) >
4706 getCmpOperandFoldingProfit(RHS, *Subtarget)) {
4707 std::swap(LHS, RHS);
4708 if (CompareType == ARMISD::CMP)
4710 }
4711 }
4712
4713 // If the RHS is a constant zero then the V (overflow) flag will never be
4714 // set. This can allow us to simplify GE to PL or LT to MI, which can be
4715 // simpler for other passes (like the peephole optimiser) to deal with.
4716 if (isNullConstant(RHS)) {
4717 switch (CondCode) {
4718 default:
4719 break;
4720 case ARMCC::GE:
4722 break;
4723 case ARMCC::LT:
4725 break;
4726 }
4727 }
4728
4729 ARMcc = DAG.getConstant(CondCode, dl, MVT::i32);
4730 return DAG.getNode(CompareType, dl, FlagsVT, LHS, RHS);
4731}
4732
4733/// Returns a appropriate VFP CMP (fcmp{s|d}+fmstat) for the given operands.
4734SDValue ARMTargetLowering::getVFPCmp(SDValue LHS, SDValue RHS,
4735 SelectionDAG &DAG, const SDLoc &dl,
4736 bool Signaling) const {
4737 assert(Subtarget->hasFP64() || RHS.getValueType() != MVT::f64);
4738 SDValue Flags;
4740 Flags = DAG.getNode(Signaling ? ARMISD::CMPFPE : ARMISD::CMPFP, dl, FlagsVT,
4741 LHS, RHS);
4742 else
4743 Flags = DAG.getNode(Signaling ? ARMISD::CMPFPEw0 : ARMISD::CMPFPw0, dl,
4744 FlagsVT, LHS);
4745 return DAG.getNode(ARMISD::FMSTAT, dl, FlagsVT, Flags);
4746}
4747
4748// This function returns three things: the arithmetic computation itself
4749// (Value), a comparison (OverflowCmp), and a condition code (ARMcc). The
4750// comparison and the condition code define the case in which the arithmetic
4751// computation *does not* overflow.
4752std::pair<SDValue, SDValue>
4753ARMTargetLowering::getARMXALUOOp(SDValue Op, SelectionDAG &DAG,
4754 SDValue &ARMcc) const {
4755 assert(Op.getValueType() == MVT::i32 && "Unsupported value type");
4756
4757 SDValue Value, OverflowCmp;
4758 SDValue LHS = Op.getOperand(0);
4759 SDValue RHS = Op.getOperand(1);
4760 SDLoc dl(Op);
4761
4762 // FIXME: We are currently always generating CMPs because we don't support
4763 // generating CMN through the backend. This is not as good as the natural
4764 // CMP case because it causes a register dependency and cannot be folded
4765 // later.
4766
4767 switch (Op.getOpcode()) {
4768 default:
4769 llvm_unreachable("Unknown overflow instruction!");
4770 case ISD::SADDO:
4771 ARMcc = DAG.getConstant(ARMCC::VC, dl, MVT::i32);
4772 Value = DAG.getNode(ISD::ADD, dl, Op.getValueType(), LHS, RHS);
4773 OverflowCmp = DAG.getNode(ARMISD::CMP, dl, FlagsVT, Value, LHS);
4774 break;
4775 case ISD::UADDO:
4776 ARMcc = DAG.getConstant(ARMCC::HS, dl, MVT::i32);
4777 // We use ADDC here to correspond to its use in LowerALUO.
4778 // We do not use it in the USUBO case as Value may not be used.
4779 Value = DAG.getNode(ARMISD::ADDC, dl,
4780 DAG.getVTList(Op.getValueType(), MVT::i32), LHS, RHS)
4781 .getValue(0);
4782 OverflowCmp = DAG.getNode(ARMISD::CMP, dl, FlagsVT, Value, LHS);
4783 break;
4784 case ISD::SSUBO:
4785 ARMcc = DAG.getConstant(ARMCC::VC, dl, MVT::i32);
4786 Value = DAG.getNode(ISD::SUB, dl, Op.getValueType(), LHS, RHS);
4787 OverflowCmp = DAG.getNode(ARMISD::CMP, dl, FlagsVT, LHS, RHS);
4788 break;
4789 case ISD::USUBO:
4790 ARMcc = DAG.getConstant(ARMCC::HS, dl, MVT::i32);
4791 Value = DAG.getNode(ISD::SUB, dl, Op.getValueType(), LHS, RHS);
4792 OverflowCmp = DAG.getNode(ARMISD::CMP, dl, FlagsVT, LHS, RHS);
4793 break;
4794 case ISD::UMULO:
4795 // We generate a UMUL_LOHI and then check if the high word is 0.
4796 ARMcc = DAG.getConstant(ARMCC::EQ, dl, MVT::i32);
4797 Value = DAG.getNode(ISD::UMUL_LOHI, dl,
4798 DAG.getVTList(Op.getValueType(), Op.getValueType()),
4799 LHS, RHS);
4800 OverflowCmp = DAG.getNode(ARMISD::CMPZ, dl, FlagsVT, Value.getValue(1),
4801 DAG.getConstant(0, dl, MVT::i32));
4802 Value = Value.getValue(0); // We only want the low 32 bits for the result.
4803 break;
4804 case ISD::SMULO:
4805 // We generate a SMUL_LOHI and then check if all the bits of the high word
4806 // are the same as the sign bit of the low word.
4807 ARMcc = DAG.getConstant(ARMCC::EQ, dl, MVT::i32);
4808 Value = DAG.getNode(ISD::SMUL_LOHI, dl,
4809 DAG.getVTList(Op.getValueType(), Op.getValueType()),
4810 LHS, RHS);
4811 OverflowCmp = DAG.getNode(ARMISD::CMPZ, dl, FlagsVT, Value.getValue(1),
4812 DAG.getNode(ISD::SRA, dl, Op.getValueType(),
4813 Value.getValue(0),
4814 DAG.getConstant(31, dl, MVT::i32)));
4815 Value = Value.getValue(0); // We only want the low 32 bits for the result.
4816 break;
4817 } // switch (...)
4818
4819 return std::make_pair(Value, OverflowCmp);
4820}
4821
4823 SDLoc DL(Value);
4824 EVT VT = Value.getValueType();
4825
4826 if (Invert)
4827 Value = DAG.getNode(ISD::SUB, DL, MVT::i32,
4828 DAG.getConstant(1, DL, MVT::i32), Value);
4829
4830 SDValue Cmp = DAG.getNode(ARMISD::SUBC, DL, DAG.getVTList(VT, MVT::i32),
4831 Value, DAG.getConstant(1, DL, VT));
4832 return Cmp.getValue(1);
4833}
4834
4836 bool Invert) {
4837 SDLoc DL(Flags);
4838
4839 if (Invert) {
4840 // Convert flags to boolean with ADDE 0,0,Carry then compute 1 - bool.
4841 SDValue BoolCarry = DAG.getNode(
4842 ARMISD::ADDE, DL, DAG.getVTList(VT, MVT::i32),
4843 DAG.getConstant(0, DL, VT), DAG.getConstant(0, DL, VT), Flags);
4844 return DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(1, DL, VT), BoolCarry);
4845 }
4846
4847 // Now convert the carry flag into a boolean carry. We do this
4848 // using ARMISD::ADDE 0, 0, Carry
4849 return DAG.getNode(ARMISD::ADDE, DL, DAG.getVTList(VT, MVT::i32),
4850 DAG.getConstant(0, DL, VT), DAG.getConstant(0, DL, VT),
4851 Flags);
4852}
4853
4854// Value is 1 if 'V' bit is 1, else 0
4856 SDLoc DL(Flags);
4857 SDValue Zero = DAG.getConstant(0, DL, VT);
4858 SDValue One = DAG.getConstant(1, DL, VT);
4859 SDValue ARMcc = DAG.getConstant(ARMCC::VS, DL, MVT::i32);
4860 return DAG.getNode(ARMISD::CMOV, DL, VT, Zero, One, ARMcc, Flags);
4861}
4862
4863SDValue ARMTargetLowering::LowerALUO(SDValue Op, SelectionDAG &DAG) const {
4864 // Let legalize expand this if it isn't a legal type yet.
4865 if (!isTypeLegal(Op.getValueType()))
4866 return SDValue();
4867
4868 SDValue LHS = Op.getOperand(0);
4869 SDValue RHS = Op.getOperand(1);
4870 SDLoc dl(Op);
4871
4872 EVT VT = Op.getValueType();
4873 SDVTList VTs = DAG.getVTList(VT, MVT::i32);
4874 SDValue Value;
4875 SDValue Overflow;
4876 switch (Op.getOpcode()) {
4877 case ISD::UADDO:
4878 Value = DAG.getNode(ARMISD::ADDC, dl, VTs, LHS, RHS);
4879 // Convert the carry flag into a boolean value.
4880 Overflow = carryFlagToValue(Value.getValue(1), VT, DAG, false);
4881 break;
4882 case ISD::USUBO:
4883 Value = DAG.getNode(ARMISD::SUBC, dl, VTs, LHS, RHS);
4884 // Convert the carry flag into a boolean value.
4885 Overflow = carryFlagToValue(Value.getValue(1), VT, DAG, true);
4886 break;
4887 default: {
4888 // Handle other operations with getARMXALUOOp
4889 SDValue OverflowCmp, ARMcc;
4890 std::tie(Value, OverflowCmp) = getARMXALUOOp(Op, DAG, ARMcc);
4891 // We use 0 and 1 as false and true values.
4892 // ARMcc represents the "no overflow" condition (e.g., VC for signed ops).
4893 // CMOV operand order is (FalseVal, TrueVal), so we put 1 in FalseVal
4894 // position to get Overflow=1 when the "no overflow" condition is false.
4895 Overflow =
4896 DAG.getNode(ARMISD::CMOV, dl, MVT::i32,
4897 DAG.getConstant(1, dl, MVT::i32), // FalseVal: overflow
4898 DAG.getConstant(0, dl, MVT::i32), // TrueVal: no overflow
4899 ARMcc, OverflowCmp);
4900 break;
4901 }
4902 }
4903
4904 return DAG.getNode(ISD::MERGE_VALUES, dl, VTs, Value, Overflow);
4905}
4906
4908 const ARMSubtarget *Subtarget) {
4909 EVT VT = Op.getValueType();
4910 if (!Subtarget->hasV6Ops() || !Subtarget->hasDSP() || Subtarget->isThumb1Only())
4911 return SDValue();
4912 if (!VT.isSimple())
4913 return SDValue();
4914
4915 unsigned NewOpcode;
4916 switch (VT.getSimpleVT().SimpleTy) {
4917 default:
4918 return SDValue();
4919 case MVT::i8:
4920 switch (Op->getOpcode()) {
4921 case ISD::UADDSAT:
4922 NewOpcode = ARMISD::UQADD8b;
4923 break;
4924 case ISD::SADDSAT:
4925 NewOpcode = ARMISD::QADD8b;
4926 break;
4927 case ISD::USUBSAT:
4928 NewOpcode = ARMISD::UQSUB8b;
4929 break;
4930 case ISD::SSUBSAT:
4931 NewOpcode = ARMISD::QSUB8b;
4932 break;
4933 }
4934 break;
4935 case MVT::i16:
4936 switch (Op->getOpcode()) {
4937 case ISD::UADDSAT:
4938 NewOpcode = ARMISD::UQADD16b;
4939 break;
4940 case ISD::SADDSAT:
4941 NewOpcode = ARMISD::QADD16b;
4942 break;
4943 case ISD::USUBSAT:
4944 NewOpcode = ARMISD::UQSUB16b;
4945 break;
4946 case ISD::SSUBSAT:
4947 NewOpcode = ARMISD::QSUB16b;
4948 break;
4949 }
4950 break;
4951 }
4952
4953 SDLoc dl(Op);
4954 SDValue Add =
4955 DAG.getNode(NewOpcode, dl, MVT::i32,
4956 DAG.getSExtOrTrunc(Op->getOperand(0), dl, MVT::i32),
4957 DAG.getSExtOrTrunc(Op->getOperand(1), dl, MVT::i32));
4958 return DAG.getNode(ISD::TRUNCATE, dl, VT, Add);
4959}
4960
4961SDValue ARMTargetLowering::LowerSELECT(SDValue Op, SelectionDAG &DAG) const {
4962 SDValue Cond = Op.getOperand(0);
4963 SDValue SelectTrue = Op.getOperand(1);
4964 SDValue SelectFalse = Op.getOperand(2);
4965 SDLoc dl(Op);
4966 unsigned Opc = Cond.getOpcode();
4967
4968 if (Cond.getResNo() == 1 &&
4969 (Opc == ISD::SADDO || Opc == ISD::UADDO || Opc == ISD::SSUBO ||
4970 Opc == ISD::USUBO)) {
4971 if (!isTypeLegal(Cond->getValueType(0)))
4972 return SDValue();
4973
4974 SDValue Value, OverflowCmp;
4975 SDValue ARMcc;
4976 std::tie(Value, OverflowCmp) = getARMXALUOOp(Cond, DAG, ARMcc);
4977 EVT VT = Op.getValueType();
4978
4979 return getCMOV(dl, VT, SelectTrue, SelectFalse, ARMcc, OverflowCmp, DAG);
4980 }
4981
4982 // Convert:
4983 //
4984 // (select (cmov 1, 0, cond), t, f) -> (cmov t, f, cond)
4985 // (select (cmov 0, 1, cond), t, f) -> (cmov f, t, cond)
4986 //
4987 if (Cond.getOpcode() == ARMISD::CMOV && Cond.hasOneUse()) {
4988 const ConstantSDNode *CMOVTrue =
4989 dyn_cast<ConstantSDNode>(Cond.getOperand(0));
4990 const ConstantSDNode *CMOVFalse =
4991 dyn_cast<ConstantSDNode>(Cond.getOperand(1));
4992
4993 if (CMOVTrue && CMOVFalse) {
4994 unsigned CMOVTrueVal = CMOVTrue->getZExtValue();
4995 unsigned CMOVFalseVal = CMOVFalse->getZExtValue();
4996
4997 SDValue True;
4998 SDValue False;
4999 if (CMOVTrueVal == 1 && CMOVFalseVal == 0) {
5000 True = SelectTrue;
5001 False = SelectFalse;
5002 } else if (CMOVTrueVal == 0 && CMOVFalseVal == 1) {
5003 True = SelectFalse;
5004 False = SelectTrue;
5005 }
5006
5007 if (True.getNode() && False.getNode())
5008 return getCMOV(dl, Op.getValueType(), True, False, Cond.getOperand(2),
5009 Cond.getOperand(3), DAG);
5010 }
5011 }
5012
5013 return DAG.getSelectCC(dl, Cond,
5014 DAG.getConstant(0, dl, Cond.getValueType()),
5015 SelectTrue, SelectFalse, ISD::SETNE);
5016}
5017
5019 bool &swpCmpOps, bool &swpVselOps) {
5020 // Start by selecting the GE condition code for opcodes that return true for
5021 // 'equality'
5022 if (CC == ISD::SETUGE || CC == ISD::SETOGE || CC == ISD::SETOLE ||
5023 CC == ISD::SETULE || CC == ISD::SETGE || CC == ISD::SETLE)
5024 CondCode = ARMCC::GE;
5025
5026 // and GT for opcodes that return false for 'equality'.
5027 else if (CC == ISD::SETUGT || CC == ISD::SETOGT || CC == ISD::SETOLT ||
5028 CC == ISD::SETULT || CC == ISD::SETGT || CC == ISD::SETLT)
5029 CondCode = ARMCC::GT;
5030
5031 // Since we are constrained to GE/GT, if the opcode contains 'less', we need
5032 // to swap the compare operands.
5033 if (CC == ISD::SETOLE || CC == ISD::SETULE || CC == ISD::SETOLT ||
5034 CC == ISD::SETULT || CC == ISD::SETLE || CC == ISD::SETLT)
5035 swpCmpOps = true;
5036
5037 // Both GT and GE are ordered comparisons, and return false for 'unordered'.
5038 // If we have an unordered opcode, we need to swap the operands to the VSEL
5039 // instruction (effectively negating the condition).
5040 //
5041 // This also has the effect of swapping which one of 'less' or 'greater'
5042 // returns true, so we also swap the compare operands. It also switches
5043 // whether we return true for 'equality', so we compensate by picking the
5044 // opposite condition code to our original choice.
5045 if (CC == ISD::SETULE || CC == ISD::SETULT || CC == ISD::SETUGE ||
5046 CC == ISD::SETUGT) {
5047 swpCmpOps = !swpCmpOps;
5048 swpVselOps = !swpVselOps;
5049 CondCode = CondCode == ARMCC::GT ? ARMCC::GE : ARMCC::GT;
5050 }
5051
5052 // 'ordered' is 'anything but unordered', so use the VS condition code and
5053 // swap the VSEL operands.
5054 if (CC == ISD::SETO) {
5055 CondCode = ARMCC::VS;
5056 swpVselOps = true;
5057 }
5058
5059 // 'unordered or not equal' is 'anything but equal', so use the EQ condition
5060 // code and swap the VSEL operands. Also do this if we don't care about the
5061 // unordered case.
5062 if (CC == ISD::SETUNE || CC == ISD::SETNE) {
5063 CondCode = ARMCC::EQ;
5064 swpVselOps = true;
5065 }
5066}
5067
5068SDValue ARMTargetLowering::getCMOV(const SDLoc &dl, EVT VT, SDValue FalseVal,
5069 SDValue TrueVal, SDValue ARMcc,
5070 SDValue Flags, SelectionDAG &DAG) const {
5071 if (!Subtarget->hasFP64() && VT == MVT::f64) {
5072 FalseVal = DAG.getNode(ARMISD::VMOVRRD, dl,
5073 DAG.getVTList(MVT::i32, MVT::i32), FalseVal);
5074 TrueVal = DAG.getNode(ARMISD::VMOVRRD, dl,
5075 DAG.getVTList(MVT::i32, MVT::i32), TrueVal);
5076
5077 SDValue TrueLow = TrueVal.getValue(0);
5078 SDValue TrueHigh = TrueVal.getValue(1);
5079 SDValue FalseLow = FalseVal.getValue(0);
5080 SDValue FalseHigh = FalseVal.getValue(1);
5081
5082 SDValue Low = DAG.getNode(ARMISD::CMOV, dl, MVT::i32, FalseLow, TrueLow,
5083 ARMcc, Flags);
5084 SDValue High = DAG.getNode(ARMISD::CMOV, dl, MVT::i32, FalseHigh, TrueHigh,
5085 ARMcc, Flags);
5086
5087 return DAG.getNode(ARMISD::VMOVDRR, dl, MVT::f64, Low, High);
5088 }
5089 return DAG.getNode(ARMISD::CMOV, dl, VT, FalseVal, TrueVal, ARMcc, Flags);
5090}
5091
5092static bool isGTorGE(ISD::CondCode CC) {
5093 return CC == ISD::SETGT || CC == ISD::SETGE;
5094}
5095
5096static bool isLTorLE(ISD::CondCode CC) {
5097 return CC == ISD::SETLT || CC == ISD::SETLE;
5098}
5099
5100// See if a conditional (LHS CC RHS ? TrueVal : FalseVal) is lower-saturating.
5101// All of these conditions (and their <= and >= counterparts) will do:
5102// x < k ? k : x
5103// x > k ? x : k
5104// k < x ? x : k
5105// k > x ? k : x
5106static bool isLowerSaturate(const SDValue LHS, const SDValue RHS,
5107 const SDValue TrueVal, const SDValue FalseVal,
5108 const ISD::CondCode CC, const SDValue K) {
5109 return (isGTorGE(CC) &&
5110 ((K == LHS && K == TrueVal) || (K == RHS && K == FalseVal))) ||
5111 (isLTorLE(CC) &&
5112 ((K == RHS && K == TrueVal) || (K == LHS && K == FalseVal)));
5113}
5114
5115// Check if two chained conditionals could be converted into SSAT or USAT.
5116//
5117// SSAT can replace a set of two conditional selectors that bound a number to an
5118// interval of type [k, ~k] when k + 1 is a power of 2. Here are some examples:
5119//
5120// x < -k ? -k : (x > k ? k : x)
5121// x < -k ? -k : (x < k ? x : k)
5122// x > -k ? (x > k ? k : x) : -k
5123// x < k ? (x < -k ? -k : x) : k
5124// etc.
5125//
5126// LLVM canonicalizes these to either a min(max()) or a max(min())
5127// pattern. This function tries to match one of these and will return a SSAT
5128// node if successful.
5129//
5130// USAT works similarly to SSAT but bounds on the interval [0, k] where k + 1
5131// is a power of 2.
5133 EVT VT = Op.getValueType();
5134 SDValue V1 = Op.getOperand(0);
5135 SDValue K1 = Op.getOperand(1);
5136 SDValue TrueVal1 = Op.getOperand(2);
5137 SDValue FalseVal1 = Op.getOperand(3);
5138 ISD::CondCode CC1 = cast<CondCodeSDNode>(Op.getOperand(4))->get();
5139
5140 const SDValue Op2 = isa<ConstantSDNode>(TrueVal1) ? FalseVal1 : TrueVal1;
5141 if (Op2.getOpcode() != ISD::SELECT_CC)
5142 return SDValue();
5143
5144 SDValue V2 = Op2.getOperand(0);
5145 SDValue K2 = Op2.getOperand(1);
5146 SDValue TrueVal2 = Op2.getOperand(2);
5147 SDValue FalseVal2 = Op2.getOperand(3);
5148 ISD::CondCode CC2 = cast<CondCodeSDNode>(Op2.getOperand(4))->get();
5149
5150 SDValue V1Tmp = V1;
5151 SDValue V2Tmp = V2;
5152
5153 // Check that the registers and the constants match a max(min()) or min(max())
5154 // pattern
5155 if (V1Tmp != TrueVal1 || V2Tmp != TrueVal2 || K1 != FalseVal1 ||
5156 K2 != FalseVal2 ||
5157 !((isGTorGE(CC1) && isLTorLE(CC2)) || (isLTorLE(CC1) && isGTorGE(CC2))))
5158 return SDValue();
5159
5160 // Check that the constant in the lower-bound check is
5161 // the opposite of the constant in the upper-bound check
5162 // in 1's complement.
5164 return SDValue();
5165
5166 int64_t Val1 = cast<ConstantSDNode>(K1)->getSExtValue();
5167 int64_t Val2 = cast<ConstantSDNode>(K2)->getSExtValue();
5168 int64_t PosVal = std::max(Val1, Val2);
5169 int64_t NegVal = std::min(Val1, Val2);
5170
5171 if (!((Val1 > Val2 && isLTorLE(CC1)) || (Val1 < Val2 && isLTorLE(CC2))) ||
5172 !isPowerOf2_64(PosVal + 1))
5173 return SDValue();
5174
5175 // Handle the difference between USAT (unsigned) and SSAT (signed)
5176 // saturation
5177 // At this point, PosVal is guaranteed to be positive
5178 uint64_t K = PosVal;
5179 SDLoc dl(Op);
5180 if (Val1 == ~Val2)
5181 return DAG.getNode(ARMISD::SSAT, dl, VT, V2Tmp,
5182 DAG.getConstant(llvm::countr_one(K), dl, VT));
5183 if (NegVal == 0)
5184 return DAG.getNode(ARMISD::USAT, dl, VT, V2Tmp,
5185 DAG.getConstant(llvm::countr_one(K), dl, VT));
5186
5187 return SDValue();
5188}
5189
5190// Check if a condition of the type x < k ? k : x can be converted into a
5191// bit operation instead of conditional moves.
5192// Currently this is allowed given:
5193// - The conditions and values match up
5194// - k is 0 or -1 (all ones)
5195// This function will not check the last condition, thats up to the caller
5196// It returns true if the transformation can be made, and in such case
5197// returns x in V, and k in SatK.
5199 SDValue &SatK)
5200{
5201 SDValue LHS = Op.getOperand(0);
5202 SDValue RHS = Op.getOperand(1);
5203 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
5204 SDValue TrueVal = Op.getOperand(2);
5205 SDValue FalseVal = Op.getOperand(3);
5206
5208 ? &RHS
5209 : nullptr;
5210
5211 // No constant operation in comparison, early out
5212 if (!K)
5213 return false;
5214
5215 SDValue KTmp = isa<ConstantSDNode>(TrueVal) ? TrueVal : FalseVal;
5216 V = (KTmp == TrueVal) ? FalseVal : TrueVal;
5217 SDValue VTmp = (K && *K == LHS) ? RHS : LHS;
5218
5219 // If the constant on left and right side, or variable on left and right,
5220 // does not match, early out
5221 if (*K != KTmp || V != VTmp)
5222 return false;
5223
5224 if (isLowerSaturate(LHS, RHS, TrueVal, FalseVal, CC, *K)) {
5225 SatK = *K;
5226 return true;
5227 }
5228
5229 return false;
5230}
5231
5232bool ARMTargetLowering::isUnsupportedFloatingType(EVT VT) const {
5233 if (VT == MVT::f32)
5234 return !Subtarget->hasVFP2Base();
5235 if (VT == MVT::f64)
5236 return !Subtarget->hasFP64();
5237 if (VT == MVT::f16)
5238 return !Subtarget->hasFullFP16();
5239 return false;
5240}
5241
5242static SDValue matchCSET(unsigned &Opcode, bool &InvertCond, SDValue TrueVal,
5243 SDValue FalseVal, const ARMSubtarget *Subtarget) {
5244 ConstantSDNode *CFVal = dyn_cast<ConstantSDNode>(FalseVal);
5245 ConstantSDNode *CTVal = dyn_cast<ConstantSDNode>(TrueVal);
5246 if (!CFVal || !CTVal || !Subtarget->hasV8_1MMainlineOps())
5247 return SDValue();
5248
5249 unsigned TVal = CTVal->getZExtValue();
5250 unsigned FVal = CFVal->getZExtValue();
5251
5252 Opcode = 0;
5253 InvertCond = false;
5254 if (TVal == ~FVal) {
5255 Opcode = ARMISD::CSINV;
5256 } else if (TVal == ~FVal + 1) {
5257 Opcode = ARMISD::CSNEG;
5258 } else if (TVal + 1 == FVal) {
5259 Opcode = ARMISD::CSINC;
5260 } else if (TVal == FVal + 1) {
5261 Opcode = ARMISD::CSINC;
5262 std::swap(TrueVal, FalseVal);
5263 std::swap(TVal, FVal);
5264 InvertCond = !InvertCond;
5265 } else {
5266 return SDValue();
5267 }
5268
5269 // If one of the constants is cheaper than another, materialise the
5270 // cheaper one and let the csel generate the other.
5271 if (Opcode != ARMISD::CSINC &&
5272 HasLowerConstantMaterializationCost(FVal, TVal, Subtarget)) {
5273 std::swap(TrueVal, FalseVal);
5274 std::swap(TVal, FVal);
5275 InvertCond = !InvertCond;
5276 }
5277
5278 // Attempt to use ZR checking TVal is 0, possibly inverting the condition
5279 // to get there. CSINC not is invertable like the other two (~(~a) == a,
5280 // -(-a) == a, but (a+1)+1 != a).
5281 if (FVal == 0 && Opcode != ARMISD::CSINC) {
5282 std::swap(TrueVal, FalseVal);
5283 std::swap(TVal, FVal);
5284 InvertCond = !InvertCond;
5285 }
5286
5287 return TrueVal;
5288}
5289
5290SDValue ARMTargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const {
5291 EVT VT = Op.getValueType();
5292 SDLoc dl(Op);
5293
5294 // Try to convert two saturating conditional selects into a single SSAT
5295 if ((!Subtarget->isThumb() && Subtarget->hasV6Ops()) || Subtarget->isThumb2())
5296 if (SDValue SatValue = LowerSaturatingConditional(Op, DAG))
5297 return SatValue;
5298
5299 // Try to convert expressions of the form x < k ? k : x (and similar forms)
5300 // into more efficient bit operations, which is possible when k is 0 or -1
5301 // On ARM and Thumb-2 which have flexible operand 2 this will result in
5302 // single instructions. On Thumb the shift and the bit operation will be two
5303 // instructions.
5304 // Only allow this transformation on full-width (32-bit) operations
5305 SDValue LowerSatConstant;
5306 SDValue SatValue;
5307 if (VT == MVT::i32 &&
5308 isLowerSaturatingConditional(Op, SatValue, LowerSatConstant)) {
5309 SDValue ShiftV = DAG.getNode(ISD::SRA, dl, VT, SatValue,
5310 DAG.getConstant(31, dl, VT));
5311 if (isNullConstant(LowerSatConstant)) {
5312 SDValue NotShiftV = DAG.getNode(ISD::XOR, dl, VT, ShiftV,
5313 DAG.getAllOnesConstant(dl, VT));
5314 return DAG.getNode(ISD::AND, dl, VT, SatValue, NotShiftV);
5315 } else if (isAllOnesConstant(LowerSatConstant))
5316 return DAG.getNode(ISD::OR, dl, VT, SatValue, ShiftV);
5317 }
5318
5319 SDValue LHS = Op.getOperand(0);
5320 SDValue RHS = Op.getOperand(1);
5321 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
5322 SDValue TrueVal = Op.getOperand(2);
5323 SDValue FalseVal = Op.getOperand(3);
5324 ConstantSDNode *CFVal = dyn_cast<ConstantSDNode>(FalseVal);
5325 ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(RHS);
5326 if (Op.getValueType().isInteger()) {
5327
5328 // Check for SMAX(lhs, 0) and SMIN(lhs, 0) patterns.
5329 // (SELECT_CC setgt, lhs, 0, lhs, 0) -> (BIC lhs, (SRA lhs, typesize-1))
5330 // (SELECT_CC setlt, lhs, 0, lhs, 0) -> (AND lhs, (SRA lhs, typesize-1))
5331 // Both require less instructions than compare and conditional select.
5332 if ((CC == ISD::SETGT || CC == ISD::SETLT) && LHS == TrueVal && RHSC &&
5333 RHSC->isZero() && CFVal && CFVal->isZero() &&
5334 LHS.getValueType() == RHS.getValueType()) {
5335 EVT VT = LHS.getValueType();
5336 SDValue Shift =
5337 DAG.getNode(ISD::SRA, dl, VT, LHS,
5338 DAG.getConstant(VT.getSizeInBits() - 1, dl, VT));
5339
5340 if (CC == ISD::SETGT)
5341 Shift = DAG.getNOT(dl, Shift, VT);
5342
5343 return DAG.getNode(ISD::AND, dl, VT, LHS, Shift);
5344 }
5345
5346 // (SELECT_CC setlt, x, 0, 1, 0) -> SRL(x, bw-1)
5347 if (CC == ISD::SETLT && isNullConstant(RHS) && isOneConstant(TrueVal) &&
5348 isNullConstant(FalseVal) && LHS.getValueType() == VT)
5349 return DAG.getNode(ISD::SRL, dl, VT, LHS,
5350 DAG.getConstant(VT.getSizeInBits() - 1, dl, VT));
5351 }
5352
5353 if (LHS.getValueType() == MVT::i32) {
5354 unsigned Opcode;
5355 bool InvertCond;
5356 if (SDValue Op =
5357 matchCSET(Opcode, InvertCond, TrueVal, FalseVal, Subtarget)) {
5358 if (InvertCond)
5359 CC = ISD::getSetCCInverse(CC, LHS.getValueType());
5360
5361 SDValue ARMcc;
5362 SDValue Cmp = getARMCmp(LHS, RHS, CC, ARMcc, DAG, dl);
5363 EVT VT = Op.getValueType();
5364 return DAG.getNode(Opcode, dl, VT, Op, Op, ARMcc, Cmp);
5365 }
5366 }
5367
5368 if (isUnsupportedFloatingType(LHS.getValueType())) {
5369 softenSetCCOperands(DAG, LHS.getValueType(), LHS, RHS, CC, dl, LHS, RHS);
5370
5371 // If softenSetCCOperands only returned one value, we should compare it to
5372 // zero.
5373 if (!RHS.getNode()) {
5374 RHS = DAG.getConstant(0, dl, LHS.getValueType());
5375 CC = ISD::SETNE;
5376 }
5377 }
5378
5379 if (LHS.getValueType() == MVT::i32) {
5380 // Try to generate VSEL on ARMv8.
5381 // The VSEL instruction can't use all the usual ARM condition
5382 // codes: it only has two bits to select the condition code, so it's
5383 // constrained to use only GE, GT, VS and EQ.
5384 //
5385 // To implement all the various ISD::SETXXX opcodes, we sometimes need to
5386 // swap the operands of the previous compare instruction (effectively
5387 // inverting the compare condition, swapping 'less' and 'greater') and
5388 // sometimes need to swap the operands to the VSEL (which inverts the
5389 // condition in the sense of firing whenever the previous condition didn't)
5390 if (Subtarget->hasFPARMv8Base() && (TrueVal.getValueType() == MVT::f16 ||
5391 TrueVal.getValueType() == MVT::f32 ||
5392 TrueVal.getValueType() == MVT::f64)) {
5394 if (CondCode == ARMCC::LT || CondCode == ARMCC::LE ||
5395 CondCode == ARMCC::VC || CondCode == ARMCC::NE) {
5396 CC = ISD::getSetCCInverse(CC, LHS.getValueType());
5397 std::swap(TrueVal, FalseVal);
5398 }
5399 }
5400
5401 SDValue ARMcc;
5402 SDValue Cmp = getARMCmp(LHS, RHS, CC, ARMcc, DAG, dl);
5403 // Choose GE over PL, which vsel does now support
5404 if (ARMcc->getAsZExtVal() == ARMCC::PL)
5405 ARMcc = DAG.getConstant(ARMCC::GE, dl, MVT::i32);
5406 return getCMOV(dl, VT, FalseVal, TrueVal, ARMcc, Cmp, DAG);
5407 }
5408
5409 ARMCC::CondCodes CondCode, CondCode2;
5410 FPCCToARMCC(CC, CondCode, CondCode2);
5411
5412 // Normalize the fp compare. If RHS is zero we prefer to keep it there so we
5413 // match CMPFPw0 instead of CMPFP, though we don't do this for f16 because we
5414 // must use VSEL (limited condition codes), due to not having conditional f16
5415 // moves.
5416 if (Subtarget->hasFPARMv8Base() &&
5417 !(isFloatingPointZero(RHS) && TrueVal.getValueType() != MVT::f16) &&
5418 (TrueVal.getValueType() == MVT::f16 ||
5419 TrueVal.getValueType() == MVT::f32 ||
5420 TrueVal.getValueType() == MVT::f64)) {
5421 bool swpCmpOps = false;
5422 bool swpVselOps = false;
5423 checkVSELConstraints(CC, CondCode, swpCmpOps, swpVselOps);
5424
5425 if (CondCode == ARMCC::GT || CondCode == ARMCC::GE ||
5426 CondCode == ARMCC::VS || CondCode == ARMCC::EQ) {
5427 if (swpCmpOps)
5428 std::swap(LHS, RHS);
5429 if (swpVselOps)
5430 std::swap(TrueVal, FalseVal);
5431 }
5432 }
5433
5434 SDValue ARMcc = DAG.getConstant(CondCode, dl, MVT::i32);
5435 SDValue Cmp = getVFPCmp(LHS, RHS, DAG, dl);
5436 SDValue Result = getCMOV(dl, VT, FalseVal, TrueVal, ARMcc, Cmp, DAG);
5437 if (CondCode2 != ARMCC::AL) {
5438 SDValue ARMcc2 = DAG.getConstant(CondCode2, dl, MVT::i32);
5439 Result = getCMOV(dl, VT, Result, TrueVal, ARMcc2, Cmp, DAG);
5440 }
5441 return Result;
5442}
5443
5444/// canChangeToInt - Given the fp compare operand, return true if it is suitable
5445/// to morph to an integer compare sequence.
5446static bool canChangeToInt(SDValue Op, bool &SeenZero,
5447 const ARMSubtarget *Subtarget) {
5448 SDNode *N = Op.getNode();
5449 if (!N->hasOneUse())
5450 // Otherwise it requires moving the value from fp to integer registers.
5451 return false;
5452 if (!N->getNumValues())
5453 return false;
5454 EVT VT = Op.getValueType();
5455 if (VT != MVT::f32 && !Subtarget->isFPBrccSlow())
5456 // f32 case is generally profitable. f64 case only makes sense when vcmpe +
5457 // vmrs are very slow, e.g. cortex-a8.
5458 return false;
5459
5460 if (isFloatingPointZero(Op)) {
5461 SeenZero = true;
5462 return true;
5463 }
5464 return ISD::isNormalLoad(N);
5465}
5466
5469 return DAG.getConstant(0, SDLoc(Op), MVT::i32);
5470
5472 return DAG.getLoad(MVT::i32, SDLoc(Op), Ld->getChain(), Ld->getBasePtr(),
5473 Ld->getPointerInfo(), Ld->getAlign(),
5474 Ld->getMemOperand()->getFlags());
5475
5476 llvm_unreachable("Unknown VFP cmp argument!");
5477}
5478
5480 SDValue &RetVal1, SDValue &RetVal2) {
5481 SDLoc dl(Op);
5482
5483 if (isFloatingPointZero(Op)) {
5484 RetVal1 = DAG.getConstant(0, dl, MVT::i32);
5485 RetVal2 = DAG.getConstant(0, dl, MVT::i32);
5486 return;
5487 }
5488
5489 if (LoadSDNode *Ld = dyn_cast<LoadSDNode>(Op)) {
5490 SDValue Ptr = Ld->getBasePtr();
5491 RetVal1 =
5492 DAG.getLoad(MVT::i32, dl, Ld->getChain(), Ptr, Ld->getPointerInfo(),
5493 Ld->getAlign(), Ld->getMemOperand()->getFlags());
5494
5495 EVT PtrType = Ptr.getValueType();
5496 SDValue NewPtr = DAG.getNode(ISD::ADD, dl,
5497 PtrType, Ptr, DAG.getConstant(4, dl, PtrType));
5498 RetVal2 = DAG.getLoad(MVT::i32, dl, Ld->getChain(), NewPtr,
5499 Ld->getPointerInfo().getWithOffset(4),
5500 commonAlignment(Ld->getAlign(), 4),
5501 Ld->getMemOperand()->getFlags());
5502 return;
5503 }
5504
5505 llvm_unreachable("Unknown VFP cmp argument!");
5506}
5507
5508/// OptimizeVFPBrcond - With nnan and without daz, it's legal to optimize some
5509/// f32 and even f64 comparisons to integer ones.
5510SDValue
5511ARMTargetLowering::OptimizeVFPBrcond(SDValue Op, SelectionDAG &DAG) const {
5512 SDValue Chain = Op.getOperand(0);
5513 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
5514 SDValue LHS = Op.getOperand(2);
5515 SDValue RHS = Op.getOperand(3);
5516 SDValue Dest = Op.getOperand(4);
5517 SDLoc dl(Op);
5518
5519 bool LHSSeenZero = false;
5520 bool LHSOk = canChangeToInt(LHS, LHSSeenZero, Subtarget);
5521 bool RHSSeenZero = false;
5522 bool RHSOk = canChangeToInt(RHS, RHSSeenZero, Subtarget);
5523 if (LHSOk && RHSOk && (LHSSeenZero || RHSSeenZero)) {
5524 // If unsafe fp math optimization is enabled and there are no other uses of
5525 // the CMP operands, and the condition code is EQ or NE, we can optimize it
5526 // to an integer comparison.
5527 if (CC == ISD::SETOEQ)
5528 CC = ISD::SETEQ;
5529 else if (CC == ISD::SETUNE)
5530 CC = ISD::SETNE;
5531
5532 SDValue Mask = DAG.getConstant(0x7fffffff, dl, MVT::i32);
5533 SDValue ARMcc;
5534 if (LHS.getValueType() == MVT::f32) {
5535 LHS = DAG.getNode(ISD::AND, dl, MVT::i32,
5536 bitcastf32Toi32(LHS, DAG), Mask);
5537 RHS = DAG.getNode(ISD::AND, dl, MVT::i32,
5538 bitcastf32Toi32(RHS, DAG), Mask);
5539 SDValue Cmp = getARMCmp(LHS, RHS, CC, ARMcc, DAG, dl);
5540 return DAG.getNode(ARMISD::BRCOND, dl, MVT::Other, Chain, Dest, ARMcc,
5541 Cmp);
5542 }
5543
5544 SDValue LHS1, LHS2;
5545 SDValue RHS1, RHS2;
5546 expandf64Toi32(LHS, DAG, LHS1, LHS2);
5547 expandf64Toi32(RHS, DAG, RHS1, RHS2);
5548 LHS2 = DAG.getNode(ISD::AND, dl, MVT::i32, LHS2, Mask);
5549 RHS2 = DAG.getNode(ISD::AND, dl, MVT::i32, RHS2, Mask);
5551 ARMcc = DAG.getConstant(CondCode, dl, MVT::i32);
5552 SDValue Ops[] = { Chain, ARMcc, LHS1, LHS2, RHS1, RHS2, Dest };
5553 return DAG.getNode(ARMISD::BCC_i64, dl, MVT::Other, Ops);
5554 }
5555
5556 return SDValue();
5557}
5558
5559// Generate CMP + CMOV for integer abs.
5560SDValue ARMTargetLowering::LowerABS(SDValue Op, SelectionDAG &DAG) const {
5561 SDLoc DL(Op);
5562
5563 SDValue Neg = DAG.getNegative(Op.getOperand(0), DL, MVT::i32);
5564
5565 // Generate CMP & CMOV.
5566 SDValue Cmp = DAG.getNode(ARMISD::CMP, DL, FlagsVT, Op.getOperand(0),
5567 DAG.getConstant(0, DL, MVT::i32));
5568 return DAG.getNode(ARMISD::CMOV, DL, MVT::i32, Op.getOperand(0), Neg,
5569 DAG.getConstant(ARMCC::MI, DL, MVT::i32), Cmp);
5570}
5571
5573 ARMCC::CondCodes CondCode =
5574 (ARMCC::CondCodes)cast<ConstantSDNode>(ARMcc)->getZExtValue();
5575 CondCode = ARMCC::getOppositeCondition(CondCode);
5576 return DAG.getConstant(CondCode, SDLoc(ARMcc), MVT::i32);
5577}
5578
5579SDValue ARMTargetLowering::LowerBRCOND(SDValue Op, SelectionDAG &DAG) const {
5580 SDValue Chain = Op.getOperand(0);
5581 SDValue Cond = Op.getOperand(1);
5582 SDValue Dest = Op.getOperand(2);
5583 SDLoc dl(Op);
5584
5585 // Optimize {s|u}{add|sub|mul}.with.overflow feeding into a branch
5586 // instruction.
5587 unsigned Opc = Cond.getOpcode();
5588 bool OptimizeMul = (Opc == ISD::SMULO || Opc == ISD::UMULO) &&
5589 !Subtarget->isThumb1Only();
5590 if (Cond.getResNo() == 1 &&
5591 (Opc == ISD::SADDO || Opc == ISD::UADDO || Opc == ISD::SSUBO ||
5592 Opc == ISD::USUBO || OptimizeMul)) {
5593 // Only lower legal XALUO ops.
5594 if (!isTypeLegal(Cond->getValueType(0)))
5595 return SDValue();
5596
5597 // The actual operation with overflow check.
5598 SDValue Value, OverflowCmp;
5599 SDValue ARMcc;
5600 std::tie(Value, OverflowCmp) = getARMXALUOOp(Cond, DAG, ARMcc);
5601
5602 // Reverse the condition code.
5603 ARMcc = getInvertedARMCondCode(ARMcc, DAG);
5604
5605 return DAG.getNode(ARMISD::BRCOND, dl, MVT::Other, Chain, Dest, ARMcc,
5606 OverflowCmp);
5607 }
5608
5609 return SDValue();
5610}
5611
5612SDValue ARMTargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const {
5613 SDValue Chain = Op.getOperand(0);
5614 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
5615 SDValue LHS = Op.getOperand(2);
5616 SDValue RHS = Op.getOperand(3);
5617 SDValue Dest = Op.getOperand(4);
5618 SDLoc dl(Op);
5619
5620 if (isUnsupportedFloatingType(LHS.getValueType())) {
5621 softenSetCCOperands(DAG, LHS.getValueType(), LHS, RHS, CC, dl, LHS, RHS);
5622
5623 // If softenSetCCOperands only returned one value, we should compare it to
5624 // zero.
5625 if (!RHS.getNode()) {
5626 RHS = DAG.getConstant(0, dl, LHS.getValueType());
5627 CC = ISD::SETNE;
5628 }
5629 }
5630
5631 // Optimize {s|u}{add|sub|mul}.with.overflow feeding into a branch
5632 // instruction.
5633 unsigned Opc = LHS.getOpcode();
5634 bool OptimizeMul = (Opc == ISD::SMULO || Opc == ISD::UMULO) &&
5635 !Subtarget->isThumb1Only();
5636 if (LHS.getResNo() == 1 && (isOneConstant(RHS) || isNullConstant(RHS)) &&
5637 (Opc == ISD::SADDO || Opc == ISD::UADDO || Opc == ISD::SSUBO ||
5638 Opc == ISD::USUBO || OptimizeMul) &&
5639 (CC == ISD::SETEQ || CC == ISD::SETNE)) {
5640 // Only lower legal XALUO ops.
5641 if (!isTypeLegal(LHS->getValueType(0)))
5642 return SDValue();
5643
5644 // The actual operation with overflow check.
5645 SDValue Value, OverflowCmp;
5646 SDValue ARMcc;
5647 std::tie(Value, OverflowCmp) = getARMXALUOOp(LHS.getValue(0), DAG, ARMcc);
5648
5649 if ((CC == ISD::SETNE) != isOneConstant(RHS)) {
5650 // Reverse the condition code.
5651 ARMcc = getInvertedARMCondCode(ARMcc, DAG);
5652 }
5653
5654 return DAG.getNode(ARMISD::BRCOND, dl, MVT::Other, Chain, Dest, ARMcc,
5655 OverflowCmp);
5656 }
5657
5658 if (LHS.getValueType() == MVT::i32) {
5659 SDValue ARMcc;
5660 SDValue Cmp = getARMCmp(LHS, RHS, CC, ARMcc, DAG, dl);
5661 return DAG.getNode(ARMISD::BRCOND, dl, MVT::Other, Chain, Dest, ARMcc, Cmp);
5662 }
5663
5664 SDNodeFlags Flags = Op->getFlags();
5665 if (Flags.hasNoNaNs() &&
5666 DAG.getDenormalMode(MVT::f32) == DenormalMode::getIEEE() &&
5667 DAG.getDenormalMode(MVT::f64) == DenormalMode::getIEEE() &&
5668 (CC == ISD::SETEQ || CC == ISD::SETOEQ || CC == ISD::SETNE ||
5669 CC == ISD::SETUNE)) {
5670 if (SDValue Result = OptimizeVFPBrcond(Op, DAG))
5671 return Result;
5672 }
5673
5674 ARMCC::CondCodes CondCode, CondCode2;
5675 FPCCToARMCC(CC, CondCode, CondCode2);
5676
5677 SDValue ARMcc = DAG.getConstant(CondCode, dl, MVT::i32);
5678 SDValue Cmp = getVFPCmp(LHS, RHS, DAG, dl);
5679 SDValue Ops[] = {Chain, Dest, ARMcc, Cmp};
5680 SDValue Res = DAG.getNode(ARMISD::BRCOND, dl, MVT::Other, Ops);
5681 if (CondCode2 != ARMCC::AL) {
5682 ARMcc = DAG.getConstant(CondCode2, dl, MVT::i32);
5683 SDValue Ops[] = {Res, Dest, ARMcc, Cmp};
5684 Res = DAG.getNode(ARMISD::BRCOND, dl, MVT::Other, Ops);
5685 }
5686 return Res;
5687}
5688
5689SDValue ARMTargetLowering::LowerBR_JT(SDValue Op, SelectionDAG &DAG) const {
5690 SDValue Chain = Op.getOperand(0);
5691 SDValue Table = Op.getOperand(1);
5692 SDValue Index = Op.getOperand(2);
5693 SDLoc dl(Op);
5694
5695 EVT PTy = getPointerTy(DAG.getDataLayout());
5696 JumpTableSDNode *JT = cast<JumpTableSDNode>(Table);
5697 SDValue JTI = DAG.getTargetJumpTable(JT->getIndex(), PTy);
5698 Table = DAG.getNode(ARMISD::WrapperJT, dl, MVT::i32, JTI);
5699 Index = DAG.getNode(ISD::MUL, dl, PTy, Index, DAG.getConstant(4, dl, PTy));
5700 SDValue Addr = DAG.getNode(ISD::ADD, dl, PTy, Table, Index);
5701 if (Subtarget->isThumb2() || (Subtarget->hasV8MBaselineOps() && Subtarget->isThumb())) {
5702 // Thumb2 and ARMv8-M use a two-level jump. That is, it jumps into the jump table
5703 // which does another jump to the destination. This also makes it easier
5704 // to translate it to TBB / TBH later (Thumb2 only).
5705 // FIXME: This might not work if the function is extremely large.
5706 return DAG.getNode(ARMISD::BR2_JT, dl, MVT::Other, Chain,
5707 Addr, Op.getOperand(2), JTI);
5708 }
5709 if (isPositionIndependent() || Subtarget->isROPI()) {
5710 Addr =
5711 DAG.getLoad((EVT)MVT::i32, dl, Chain, Addr,
5713 Chain = Addr.getValue(1);
5714 Addr = DAG.getNode(ISD::ADD, dl, PTy, Table, Addr);
5715 return DAG.getNode(ARMISD::BR_JT, dl, MVT::Other, Chain, Addr, JTI);
5716 } else {
5717 Addr =
5718 DAG.getLoad(PTy, dl, Chain, Addr,
5720 Chain = Addr.getValue(1);
5721 return DAG.getNode(ARMISD::BR_JT, dl, MVT::Other, Chain, Addr, JTI);
5722 }
5723}
5724
5726 EVT VT = Op.getValueType();
5727 SDLoc dl(Op);
5728
5729 if (Op.getValueType().getVectorElementType() == MVT::i32) {
5730 if (Op.getOperand(0).getValueType().getVectorElementType() == MVT::f32)
5731 return Op;
5732 return DAG.UnrollVectorOp(Op.getNode());
5733 }
5734
5735 const bool HasFullFP16 = DAG.getSubtarget<ARMSubtarget>().hasFullFP16();
5736
5737 EVT NewTy;
5738 const EVT OpTy = Op.getOperand(0).getValueType();
5739 if (OpTy == MVT::v4f32)
5740 NewTy = MVT::v4i32;
5741 else if (OpTy == MVT::v4f16 && HasFullFP16)
5742 NewTy = MVT::v4i16;
5743 else if (OpTy == MVT::v8f16 && HasFullFP16)
5744 NewTy = MVT::v8i16;
5745 else
5746 llvm_unreachable("Invalid type for custom lowering!");
5747
5748 if (VT != MVT::v4i16 && VT != MVT::v8i16)
5749 return DAG.UnrollVectorOp(Op.getNode());
5750
5751 Op = DAG.getNode(Op.getOpcode(), dl, NewTy, Op.getOperand(0));
5752 return DAG.getNode(ISD::TRUNCATE, dl, VT, Op);
5753}
5754
5755SDValue ARMTargetLowering::LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG) const {
5756 EVT VT = Op.getValueType();
5757 if (VT.isVector())
5758 return LowerVectorFP_TO_INT(Op, DAG);
5759
5760 bool IsStrict = Op->isStrictFPOpcode();
5761 SDValue SrcVal = Op.getOperand(IsStrict ? 1 : 0);
5762
5763 if (isUnsupportedFloatingType(SrcVal.getValueType())) {
5764 RTLIB::Libcall LC;
5765 if (Op.getOpcode() == ISD::FP_TO_SINT ||
5766 Op.getOpcode() == ISD::STRICT_FP_TO_SINT)
5767 LC = RTLIB::getFPTOSINT(SrcVal.getValueType(),
5768 Op.getValueType());
5769 else
5770 LC = RTLIB::getFPTOUINT(SrcVal.getValueType(),
5771 Op.getValueType());
5772 SDLoc Loc(Op);
5773 MakeLibCallOptions CallOptions;
5774 SDValue Chain = IsStrict ? Op.getOperand(0) : SDValue();
5775 SDValue Result;
5776 std::tie(Result, Chain) = makeLibCall(DAG, LC, Op.getValueType(), SrcVal,
5777 CallOptions, Loc, Chain);
5778 return IsStrict ? DAG.getMergeValues({Result, Chain}, Loc) : Result;
5779 }
5780
5781 return Op;
5782}
5783
5785 const ARMSubtarget *Subtarget) {
5786 EVT VT = Op.getValueType();
5787 EVT ToVT = cast<VTSDNode>(Op.getOperand(1))->getVT();
5788 EVT FromVT = Op.getOperand(0).getValueType();
5789
5790 if (VT == MVT::i32 && ToVT == MVT::i32 && FromVT == MVT::f32)
5791 return Op;
5792 if (VT == MVT::i32 && ToVT == MVT::i32 && FromVT == MVT::f64 &&
5793 Subtarget->hasFP64())
5794 return Op;
5795 if (VT == MVT::i32 && ToVT == MVT::i32 && FromVT == MVT::f16 &&
5796 Subtarget->hasFullFP16())
5797 return Op;
5798 if (VT == MVT::v4i32 && ToVT == MVT::i32 && FromVT == MVT::v4f32 &&
5799 Subtarget->hasMVEFloatOps())
5800 return Op;
5801 if (VT == MVT::v8i16 && ToVT == MVT::i16 && FromVT == MVT::v8f16 &&
5802 Subtarget->hasMVEFloatOps())
5803 return Op;
5804
5805 if (FromVT != MVT::v4f32 && FromVT != MVT::v8f16)
5806 return SDValue();
5807
5808 SDLoc DL(Op);
5809 bool IsSigned = Op.getOpcode() == ISD::FP_TO_SINT_SAT;
5810 unsigned BW = ToVT.getScalarSizeInBits() - IsSigned;
5811 SDValue CVT = DAG.getNode(Op.getOpcode(), DL, VT, Op.getOperand(0),
5812 DAG.getValueType(VT.getScalarType()));
5813 SDValue Max = DAG.getNode(IsSigned ? ISD::SMIN : ISD::UMIN, DL, VT, CVT,
5814 DAG.getConstant((1 << BW) - 1, DL, VT));
5815 if (IsSigned)
5816 Max = DAG.getNode(ISD::SMAX, DL, VT, Max,
5817 DAG.getSignedConstant(-(1 << BW), DL, VT));
5818 return Max;
5819}
5820
5822 EVT VT = Op.getValueType();
5823 SDLoc dl(Op);
5824
5825 if (Op.getOperand(0).getValueType().getVectorElementType() == MVT::i32) {
5826 if (VT.getVectorElementType() == MVT::f32)
5827 return Op;
5828 return DAG.UnrollVectorOp(Op.getNode());
5829 }
5830
5831 assert((Op.getOperand(0).getValueType() == MVT::v4i16 ||
5832 Op.getOperand(0).getValueType() == MVT::v8i16) &&
5833 "Invalid type for custom lowering!");
5834
5835 const bool HasFullFP16 = DAG.getSubtarget<ARMSubtarget>().hasFullFP16();
5836
5837 EVT DestVecType;
5838 if (VT == MVT::v4f32)
5839 DestVecType = MVT::v4i32;
5840 else if (VT == MVT::v4f16 && HasFullFP16)
5841 DestVecType = MVT::v4i16;
5842 else if (VT == MVT::v8f16 && HasFullFP16)
5843 DestVecType = MVT::v8i16;
5844 else
5845 return DAG.UnrollVectorOp(Op.getNode());
5846
5847 unsigned CastOpc;
5848 unsigned Opc;
5849 switch (Op.getOpcode()) {
5850 default: llvm_unreachable("Invalid opcode!");
5851 case ISD::SINT_TO_FP:
5852 CastOpc = ISD::SIGN_EXTEND;
5854 break;
5855 case ISD::UINT_TO_FP:
5856 CastOpc = ISD::ZERO_EXTEND;
5858 break;
5859 }
5860
5861 Op = DAG.getNode(CastOpc, dl, DestVecType, Op.getOperand(0));
5862 return DAG.getNode(Opc, dl, VT, Op);
5863}
5864
5865SDValue ARMTargetLowering::LowerINT_TO_FP(SDValue Op, SelectionDAG &DAG) const {
5866 EVT VT = Op.getValueType();
5867 if (VT.isVector())
5868 return LowerVectorINT_TO_FP(Op, DAG);
5869
5870 bool IsStrict = Op->isStrictFPOpcode();
5871 SDValue SrcVal = Op.getOperand(IsStrict ? 1 : 0);
5872
5873 if (isUnsupportedFloatingType(VT)) {
5874 RTLIB::Libcall LC;
5875 if (Op.getOpcode() == ISD::SINT_TO_FP ||
5876 Op.getOpcode() == ISD::STRICT_SINT_TO_FP)
5877 LC = RTLIB::getSINTTOFP(SrcVal.getValueType(), Op.getValueType());
5878 else
5879 LC = RTLIB::getUINTTOFP(SrcVal.getValueType(), Op.getValueType());
5880 SDLoc Loc(Op);
5881 MakeLibCallOptions CallOptions;
5882 SDValue Chain = IsStrict ? Op.getOperand(0) : SDValue();
5883 SDValue Result;
5884 std::tie(Result, Chain) = makeLibCall(DAG, LC, Op.getValueType(), SrcVal,
5885 CallOptions, Loc, Chain);
5886 return IsStrict ? DAG.getMergeValues({Result, Chain}, Loc) : Result;
5887 }
5888
5889 return Op;
5890}
5891
5892SDValue ARMTargetLowering::LowerFCOPYSIGN(SDValue Op, SelectionDAG &DAG) const {
5893 // Implement fcopysign with a fabs and a conditional fneg.
5894 SDValue Tmp0 = Op.getOperand(0);
5895 SDValue Tmp1 = Op.getOperand(1);
5896 SDLoc dl(Op);
5897 EVT VT = Op.getValueType();
5898 EVT SrcVT = Tmp1.getValueType();
5899 bool InGPR = Tmp0.getOpcode() == ISD::BITCAST ||
5900 Tmp0.getOpcode() == ARMISD::VMOVDRR;
5901 bool UseNEON = !InGPR && Subtarget->hasNEON();
5902
5903 if (UseNEON) {
5904 // Use VBSL to copy the sign bit.
5905 unsigned EncodedVal = ARM_AM::createVMOVModImm(0x6, 0x80);
5906 SDValue Mask = DAG.getNode(ARMISD::VMOVIMM, dl, MVT::v2i32,
5907 DAG.getTargetConstant(EncodedVal, dl, MVT::i32));
5908 EVT OpVT = (VT == MVT::f32) ? MVT::v2i32 : MVT::v1i64;
5909 if (VT == MVT::f64)
5910 Mask = DAG.getNode(ARMISD::VSHLIMM, dl, OpVT,
5911 DAG.getNode(ISD::BITCAST, dl, OpVT, Mask),
5912 DAG.getConstant(32, dl, MVT::i32));
5913 else /*if (VT == MVT::f32)*/
5914 Tmp0 = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, MVT::v2f32, Tmp0);
5915 if (SrcVT == MVT::f32) {
5916 Tmp1 = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, MVT::v2f32, Tmp1);
5917 if (VT == MVT::f64)
5918 Tmp1 = DAG.getNode(ARMISD::VSHLIMM, dl, OpVT,
5919 DAG.getNode(ISD::BITCAST, dl, OpVT, Tmp1),
5920 DAG.getConstant(32, dl, MVT::i32));
5921 } else if (VT == MVT::f32)
5922 Tmp1 = DAG.getNode(ARMISD::VSHRuIMM, dl, MVT::v1i64,
5923 DAG.getNode(ISD::BITCAST, dl, MVT::v1i64, Tmp1),
5924 DAG.getConstant(32, dl, MVT::i32));
5925 Tmp0 = DAG.getNode(ISD::BITCAST, dl, OpVT, Tmp0);
5926 Tmp1 = DAG.getNode(ISD::BITCAST, dl, OpVT, Tmp1);
5927
5928 SDValue AllOnes = DAG.getTargetConstant(ARM_AM::createVMOVModImm(0xe, 0xff),
5929 dl, MVT::i32);
5930 AllOnes = DAG.getNode(ARMISD::VMOVIMM, dl, MVT::v8i8, AllOnes);
5931 SDValue MaskNot = DAG.getNode(ISD::XOR, dl, OpVT, Mask,
5932 DAG.getNode(ISD::BITCAST, dl, OpVT, AllOnes));
5933
5934 SDValue Res = DAG.getNode(ISD::OR, dl, OpVT,
5935 DAG.getNode(ISD::AND, dl, OpVT, Tmp1, Mask),
5936 DAG.getNode(ISD::AND, dl, OpVT, Tmp0, MaskNot));
5937 if (VT == MVT::f32) {
5938 Res = DAG.getNode(ISD::BITCAST, dl, MVT::v2f32, Res);
5939 Res = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f32, Res,
5940 DAG.getConstant(0, dl, MVT::i32));
5941 } else {
5942 Res = DAG.getNode(ISD::BITCAST, dl, MVT::f64, Res);
5943 }
5944
5945 return Res;
5946 }
5947
5948 // Bitcast operand 1 to i32.
5949 if (SrcVT == MVT::f64)
5950 Tmp1 = DAG.getNode(ARMISD::VMOVRRD, dl, DAG.getVTList(MVT::i32, MVT::i32),
5951 Tmp1).getValue(1);
5952 Tmp1 = DAG.getNode(ISD::BITCAST, dl, MVT::i32, Tmp1);
5953
5954 // Or in the signbit with integer operations.
5955 SDValue Mask1 = DAG.getConstant(0x80000000, dl, MVT::i32);
5956 SDValue Mask2 = DAG.getConstant(0x7fffffff, dl, MVT::i32);
5957 Tmp1 = DAG.getNode(ISD::AND, dl, MVT::i32, Tmp1, Mask1);
5958 if (VT == MVT::f32) {
5959 Tmp0 = DAG.getNode(ISD::AND, dl, MVT::i32,
5960 DAG.getNode(ISD::BITCAST, dl, MVT::i32, Tmp0), Mask2);
5961 return DAG.getNode(ISD::BITCAST, dl, MVT::f32,
5962 DAG.getNode(ISD::OR, dl, MVT::i32, Tmp0, Tmp1));
5963 }
5964
5965 // f64: Or the high part with signbit and then combine two parts.
5966 Tmp0 = DAG.getNode(ARMISD::VMOVRRD, dl, DAG.getVTList(MVT::i32, MVT::i32),
5967 Tmp0);
5968 SDValue Lo = Tmp0.getValue(0);
5969 SDValue Hi = DAG.getNode(ISD::AND, dl, MVT::i32, Tmp0.getValue(1), Mask2);
5970 Hi = DAG.getNode(ISD::OR, dl, MVT::i32, Hi, Tmp1);
5971 return DAG.getNode(ARMISD::VMOVDRR, dl, MVT::f64, Lo, Hi);
5972}
5973
5974SDValue ARMTargetLowering::LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const{
5976 MachineFrameInfo &MFI = MF.getFrameInfo();
5977 MFI.setReturnAddressIsTaken(true);
5978
5979 EVT VT = Op.getValueType();
5980 SDLoc dl(Op);
5981 unsigned Depth = Op.getConstantOperandVal(0);
5982 if (Depth) {
5983 SDValue FrameAddr = LowerFRAMEADDR(Op, DAG);
5984 SDValue Offset = DAG.getConstant(4, dl, MVT::i32);
5985 return DAG.getLoad(VT, dl, DAG.getEntryNode(),
5986 DAG.getNode(ISD::ADD, dl, VT, FrameAddr, Offset),
5987 MachinePointerInfo());
5988 }
5989
5990 // Return LR, which contains the return address. Mark it an implicit live-in.
5991 Register Reg = MF.addLiveIn(ARM::LR, getRegClassFor(MVT::i32));
5992 return DAG.getCopyFromReg(DAG.getEntryNode(), dl, Reg, VT);
5993}
5994
5995SDValue ARMTargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const {
5996 const ARMBaseRegisterInfo &ARI =
5997 *static_cast<const ARMBaseRegisterInfo*>(RegInfo);
5999 MachineFrameInfo &MFI = MF.getFrameInfo();
6000 MFI.setFrameAddressIsTaken(true);
6001
6002 EVT VT = Op.getValueType();
6003 SDLoc dl(Op); // FIXME probably not meaningful
6004 unsigned Depth = Op.getConstantOperandVal(0);
6005 Register FrameReg = ARI.getFrameRegister(MF);
6006 SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, FrameReg, VT);
6007 while (Depth--)
6008 FrameAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), FrameAddr,
6009 MachinePointerInfo());
6010 return FrameAddr;
6011}
6012
6013// FIXME? Maybe this could be a TableGen attribute on some registers and
6014// this table could be generated automatically from RegInfo.
6015Register ARMTargetLowering::getRegisterByName(const char* RegName, LLT VT,
6016 const MachineFunction &MF) const {
6017 return StringSwitch<Register>(RegName)
6018 .Case("sp", ARM::SP)
6019 .Default(Register());
6020}
6021
6022// Result is 64 bit value so split into two 32 bit values and return as a
6023// pair of values.
6025 SelectionDAG &DAG) {
6026 SDLoc DL(N);
6027
6028 // This function is only supposed to be called for i64 type destination.
6029 assert(N->getValueType(0) == MVT::i64
6030 && "ExpandREAD_REGISTER called for non-i64 type result.");
6031
6033 DAG.getVTList(MVT::i32, MVT::i32, MVT::Other),
6034 N->getOperand(0),
6035 N->getOperand(1));
6036
6037 Results.push_back(DAG.getNode(ISD::BUILD_PAIR, DL, MVT::i64, Read.getValue(0),
6038 Read.getValue(1)));
6039 Results.push_back(Read.getValue(2)); // Chain
6040}
6041
6042/// \p BC is a bitcast that is about to be turned into a VMOVDRR.
6043/// When \p DstVT, the destination type of \p BC, is on the vector
6044/// register bank and the source of bitcast, \p Op, operates on the same bank,
6045/// it might be possible to combine them, such that everything stays on the
6046/// vector register bank.
6047/// \p return The node that would replace \p BT, if the combine
6048/// is possible.
6050 SelectionDAG &DAG) {
6051 SDValue Op = BC->getOperand(0);
6052 EVT DstVT = BC->getValueType(0);
6053
6054 // The only vector instruction that can produce a scalar (remember,
6055 // since the bitcast was about to be turned into VMOVDRR, the source
6056 // type is i64) from a vector is EXTRACT_VECTOR_ELT.
6057 // Moreover, we can do this combine only if there is one use.
6058 // Finally, if the destination type is not a vector, there is not
6059 // much point on forcing everything on the vector bank.
6060 if (!DstVT.isVector() || Op.getOpcode() != ISD::EXTRACT_VECTOR_ELT ||
6061 !Op.hasOneUse())
6062 return SDValue();
6063
6064 // If the index is not constant, we will introduce an additional
6065 // multiply that will stick.
6066 // Give up in that case.
6067 ConstantSDNode *Index = dyn_cast<ConstantSDNode>(Op.getOperand(1));
6068 if (!Index)
6069 return SDValue();
6070 unsigned DstNumElt = DstVT.getVectorNumElements();
6071
6072 // Compute the new index.
6073 const APInt &APIntIndex = Index->getAPIntValue();
6074 APInt NewIndex(APIntIndex.getBitWidth(), DstNumElt);
6075 NewIndex *= APIntIndex;
6076 // Check if the new constant index fits into i32.
6077 if (NewIndex.getBitWidth() > 32)
6078 return SDValue();
6079
6080 // vMTy bitcast(i64 extractelt vNi64 src, i32 index) ->
6081 // vMTy extractsubvector vNxMTy (bitcast vNi64 src), i32 index*M)
6082 SDLoc dl(Op);
6083 SDValue ExtractSrc = Op.getOperand(0);
6084 EVT VecVT = EVT::getVectorVT(
6085 *DAG.getContext(), DstVT.getScalarType(),
6086 ExtractSrc.getValueType().getVectorNumElements() * DstNumElt);
6087 SDValue BitCast = DAG.getNode(ISD::BITCAST, dl, VecVT, ExtractSrc);
6088 return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, DstVT, BitCast,
6089 DAG.getConstant(NewIndex.getZExtValue(), dl, MVT::i32));
6090}
6091
6092/// ExpandBITCAST - If the target supports VFP, this function is called to
6093/// expand a bit convert where either the source or destination type is i64 to
6094/// use a VMOVDRR or VMOVRRD node. This should not be done when the non-i64
6095/// operand type is illegal (e.g., v2f32 for a target that doesn't support
6096/// vectors), since the legalizer won't know what to do with that.
6097SDValue ARMTargetLowering::ExpandBITCAST(SDNode *N, SelectionDAG &DAG,
6098 const ARMSubtarget *Subtarget) const {
6099 SDLoc dl(N);
6100 SDValue Op = N->getOperand(0);
6101
6102 // This function is only supposed to be called for i16 and i64 types, either
6103 // as the source or destination of the bit convert.
6104 EVT SrcVT = Op.getValueType();
6105 EVT DstVT = N->getValueType(0);
6106
6107 if ((SrcVT == MVT::i16 || SrcVT == MVT::i32) &&
6108 (DstVT == MVT::f16 || DstVT == MVT::bf16))
6109 return MoveToHPR(SDLoc(N), DAG, MVT::i32, DstVT.getSimpleVT(),
6110 DAG.getNode(ISD::ZERO_EXTEND, SDLoc(N), MVT::i32, Op));
6111
6112 if ((DstVT == MVT::i16 || DstVT == MVT::i32) &&
6113 (SrcVT == MVT::f16 || SrcVT == MVT::bf16)) {
6114 if (Subtarget->hasFullFP16() && !Subtarget->hasBF16())
6115 Op = DAG.getBitcast(MVT::f16, Op);
6116 return DAG.getNode(
6117 ISD::TRUNCATE, SDLoc(N), DstVT,
6118 MoveFromHPR(SDLoc(N), DAG, MVT::i32, SrcVT.getSimpleVT(), Op));
6119 }
6120
6121 if (!(SrcVT == MVT::i64 || DstVT == MVT::i64))
6122 return SDValue();
6123
6124 // Turn i64->f64 into VMOVDRR.
6125 if (SrcVT == MVT::i64 && isTypeLegal(DstVT)) {
6126 // Do not force values to GPRs (this is what VMOVDRR does for the inputs)
6127 // if we can combine the bitcast with its source.
6128 if (SDValue Val = CombineVMOVDRRCandidateWithVecOp(N, DAG))
6129 return Val;
6130 SDValue Lo, Hi;
6131 std::tie(Lo, Hi) = DAG.SplitScalar(Op, dl, MVT::i32, MVT::i32);
6132 return DAG.getNode(ISD::BITCAST, dl, DstVT,
6133 DAG.getNode(ARMISD::VMOVDRR, dl, MVT::f64, Lo, Hi));
6134 }
6135
6136 // Turn f64->i64 into VMOVRRD.
6137 if (DstVT == MVT::i64 && isTypeLegal(SrcVT)) {
6138 SDValue Cvt;
6139 if (DAG.getDataLayout().isBigEndian() && SrcVT.isVector() &&
6140 SrcVT.getVectorNumElements() > 1)
6141 Cvt = DAG.getNode(ARMISD::VMOVRRD, dl,
6142 DAG.getVTList(MVT::i32, MVT::i32),
6143 DAG.getNode(ARMISD::VREV64, dl, SrcVT, Op));
6144 else
6145 Cvt = DAG.getNode(ARMISD::VMOVRRD, dl,
6146 DAG.getVTList(MVT::i32, MVT::i32), Op);
6147 // Merge the pieces into a single i64 value.
6148 return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Cvt, Cvt.getValue(1));
6149 }
6150
6151 return SDValue();
6152}
6153
6154/// getZeroVector - Returns a vector of specified type with all zero elements.
6155/// Zero vectors are used to represent vector negation and in those cases
6156/// will be implemented with the NEON VNEG instruction. However, VNEG does
6157/// not support i64 elements, so sometimes the zero vectors will need to be
6158/// explicitly constructed. Regardless, use a canonical VMOV to create the
6159/// zero vector.
6160static SDValue getZeroVector(EVT VT, SelectionDAG &DAG, const SDLoc &dl) {
6161 assert(VT.isVector() && "Expected a vector type");
6162 // The canonical modified immediate encoding of a zero vector is....0!
6163 SDValue EncodedVal = DAG.getTargetConstant(0, dl, MVT::i32);
6164 EVT VmovVT = VT.is128BitVector() ? MVT::v4i32 : MVT::v2i32;
6165 SDValue Vmov = DAG.getNode(ARMISD::VMOVIMM, dl, VmovVT, EncodedVal);
6166 return DAG.getNode(ISD::BITCAST, dl, VT, Vmov);
6167}
6168
6169/// LowerShiftRightParts - Lower SRA_PARTS, which returns two
6170/// i32 values and take a 2 x i32 value to shift plus a shift amount.
6171SDValue ARMTargetLowering::LowerShiftRightParts(SDValue Op,
6172 SelectionDAG &DAG) const {
6173 assert(Op.getNumOperands() == 3 && "Not a double-shift!");
6174 EVT VT = Op.getValueType();
6175 unsigned VTBits = VT.getSizeInBits();
6176 SDLoc dl(Op);
6177 SDValue ShOpLo = Op.getOperand(0);
6178 SDValue ShOpHi = Op.getOperand(1);
6179 SDValue ShAmt = Op.getOperand(2);
6180 SDValue ARMcc;
6181 unsigned Opc = (Op.getOpcode() == ISD::SRA_PARTS) ? ISD::SRA : ISD::SRL;
6182
6183 assert(Op.getOpcode() == ISD::SRA_PARTS || Op.getOpcode() == ISD::SRL_PARTS);
6184
6185 SDValue RevShAmt = DAG.getNode(ISD::SUB, dl, MVT::i32,
6186 DAG.getConstant(VTBits, dl, MVT::i32), ShAmt);
6187 SDValue Tmp1 = DAG.getNode(ISD::SRL, dl, VT, ShOpLo, ShAmt);
6188 SDValue ExtraShAmt = DAG.getNode(ISD::SUB, dl, MVT::i32, ShAmt,
6189 DAG.getConstant(VTBits, dl, MVT::i32));
6190 SDValue Tmp2 = DAG.getNode(ISD::SHL, dl, VT, ShOpHi, RevShAmt);
6191 SDValue LoSmallShift = DAG.getNode(ISD::OR, dl, VT, Tmp1, Tmp2);
6192 SDValue LoBigShift = DAG.getNode(Opc, dl, VT, ShOpHi, ExtraShAmt);
6193 SDValue CmpLo = getARMCmp(ExtraShAmt, DAG.getConstant(0, dl, MVT::i32),
6194 ISD::SETGE, ARMcc, DAG, dl);
6195 SDValue Lo =
6196 DAG.getNode(ARMISD::CMOV, dl, VT, LoSmallShift, LoBigShift, ARMcc, CmpLo);
6197
6198 SDValue HiSmallShift = DAG.getNode(Opc, dl, VT, ShOpHi, ShAmt);
6199 SDValue HiBigShift = Opc == ISD::SRA
6200 ? DAG.getNode(Opc, dl, VT, ShOpHi,
6201 DAG.getConstant(VTBits - 1, dl, VT))
6202 : DAG.getConstant(0, dl, VT);
6203 SDValue CmpHi = getARMCmp(ExtraShAmt, DAG.getConstant(0, dl, MVT::i32),
6204 ISD::SETGE, ARMcc, DAG, dl);
6205 SDValue Hi =
6206 DAG.getNode(ARMISD::CMOV, dl, VT, HiSmallShift, HiBigShift, ARMcc, CmpHi);
6207
6208 SDValue Ops[2] = { Lo, Hi };
6209 return DAG.getMergeValues(Ops, dl);
6210}
6211
6212/// LowerShiftLeftParts - Lower SHL_PARTS, which returns two
6213/// i32 values and take a 2 x i32 value to shift plus a shift amount.
6214SDValue ARMTargetLowering::LowerShiftLeftParts(SDValue Op,
6215 SelectionDAG &DAG) const {
6216 assert(Op.getNumOperands() == 3 && "Not a double-shift!");
6217 EVT VT = Op.getValueType();
6218 unsigned VTBits = VT.getSizeInBits();
6219 SDLoc dl(Op);
6220 SDValue ShOpLo = Op.getOperand(0);
6221 SDValue ShOpHi = Op.getOperand(1);
6222 SDValue ShAmt = Op.getOperand(2);
6223 SDValue ARMcc;
6224
6225 assert(Op.getOpcode() == ISD::SHL_PARTS);
6226 SDValue RevShAmt = DAG.getNode(ISD::SUB, dl, MVT::i32,
6227 DAG.getConstant(VTBits, dl, MVT::i32), ShAmt);
6228 SDValue Tmp1 = DAG.getNode(ISD::SRL, dl, VT, ShOpLo, RevShAmt);
6229 SDValue Tmp2 = DAG.getNode(ISD::SHL, dl, VT, ShOpHi, ShAmt);
6230 SDValue HiSmallShift = DAG.getNode(ISD::OR, dl, VT, Tmp1, Tmp2);
6231
6232 SDValue ExtraShAmt = DAG.getNode(ISD::SUB, dl, MVT::i32, ShAmt,
6233 DAG.getConstant(VTBits, dl, MVT::i32));
6234 SDValue HiBigShift = DAG.getNode(ISD::SHL, dl, VT, ShOpLo, ExtraShAmt);
6235 SDValue CmpHi = getARMCmp(ExtraShAmt, DAG.getConstant(0, dl, MVT::i32),
6236 ISD::SETGE, ARMcc, DAG, dl);
6237 SDValue Hi =
6238 DAG.getNode(ARMISD::CMOV, dl, VT, HiSmallShift, HiBigShift, ARMcc, CmpHi);
6239
6240 SDValue CmpLo = getARMCmp(ExtraShAmt, DAG.getConstant(0, dl, MVT::i32),
6241 ISD::SETGE, ARMcc, DAG, dl);
6242 SDValue LoSmallShift = DAG.getNode(ISD::SHL, dl, VT, ShOpLo, ShAmt);
6243 SDValue Lo = DAG.getNode(ARMISD::CMOV, dl, VT, LoSmallShift,
6244 DAG.getConstant(0, dl, VT), ARMcc, CmpLo);
6245
6246 SDValue Ops[2] = { Lo, Hi };
6247 return DAG.getMergeValues(Ops, dl);
6248}
6249
6250SDValue ARMTargetLowering::LowerGET_ROUNDING(SDValue Op,
6251 SelectionDAG &DAG) const {
6252 // The rounding mode is in bits 23:22 of the FPSCR.
6253 // The ARM rounding mode value to FLT_ROUNDS mapping is 0->1, 1->2, 2->3, 3->0
6254 // The formula we use to implement this is (((FPSCR + 1 << 22) >> 22) & 3)
6255 // so that the shift + and get folded into a bitfield extract.
6256 SDLoc dl(Op);
6257 SDValue Chain = Op.getOperand(0);
6258 SDValue Ops[] = {Chain,
6259 DAG.getConstant(Intrinsic::arm_get_fpscr, dl, MVT::i32)};
6260
6261 SDValue FPSCR =
6262 DAG.getNode(ISD::INTRINSIC_W_CHAIN, dl, {MVT::i32, MVT::Other}, Ops);
6263 Chain = FPSCR.getValue(1);
6264 SDValue FltRounds = DAG.getNode(ISD::ADD, dl, MVT::i32, FPSCR,
6265 DAG.getConstant(1U << 22, dl, MVT::i32));
6266 SDValue RMODE = DAG.getNode(ISD::SRL, dl, MVT::i32, FltRounds,
6267 DAG.getConstant(22, dl, MVT::i32));
6268 SDValue And = DAG.getNode(ISD::AND, dl, MVT::i32, RMODE,
6269 DAG.getConstant(3, dl, MVT::i32));
6270 return DAG.getMergeValues({And, Chain}, dl);
6271}
6272
6273SDValue ARMTargetLowering::LowerSET_ROUNDING(SDValue Op,
6274 SelectionDAG &DAG) const {
6275 SDLoc DL(Op);
6276 SDValue Chain = Op->getOperand(0);
6277 SDValue RMValue = Op->getOperand(1);
6278
6279 // The rounding mode is in bits 23:22 of the FPSCR.
6280 // The llvm.set.rounding argument value to ARM rounding mode value mapping
6281 // is 0->3, 1->0, 2->1, 3->2. The formula we use to implement this is
6282 // ((arg - 1) & 3) << 22).
6283 //
6284 // It is expected that the argument of llvm.set.rounding is within the
6285 // segment [0, 3], so NearestTiesToAway (4) is not handled here. It is
6286 // responsibility of the code generated llvm.set.rounding to ensure this
6287 // condition.
6288
6289 // Calculate new value of FPSCR[23:22].
6290 RMValue = DAG.getNode(ISD::SUB, DL, MVT::i32, RMValue,
6291 DAG.getConstant(1, DL, MVT::i32));
6292 RMValue = DAG.getNode(ISD::AND, DL, MVT::i32, RMValue,
6293 DAG.getConstant(0x3, DL, MVT::i32));
6294 RMValue = DAG.getNode(ISD::SHL, DL, MVT::i32, RMValue,
6295 DAG.getConstant(ARM::RoundingBitsPos, DL, MVT::i32));
6296
6297 // Get current value of FPSCR.
6298 SDValue Ops[] = {Chain,
6299 DAG.getConstant(Intrinsic::arm_get_fpscr, DL, MVT::i32)};
6300 SDValue FPSCR =
6301 DAG.getNode(ISD::INTRINSIC_W_CHAIN, DL, {MVT::i32, MVT::Other}, Ops);
6302 Chain = FPSCR.getValue(1);
6303 FPSCR = FPSCR.getValue(0);
6304
6305 // Put new rounding mode into FPSCR[23:22].
6306 const unsigned RMMask = ~(ARM::Rounding::rmMask << ARM::RoundingBitsPos);
6307 FPSCR = DAG.getNode(ISD::AND, DL, MVT::i32, FPSCR,
6308 DAG.getConstant(RMMask, DL, MVT::i32));
6309 FPSCR = DAG.getNode(ISD::OR, DL, MVT::i32, FPSCR, RMValue);
6310 SDValue Ops2[] = {
6311 Chain, DAG.getConstant(Intrinsic::arm_set_fpscr, DL, MVT::i32), FPSCR};
6312 return DAG.getNode(ISD::INTRINSIC_VOID, DL, MVT::Other, Ops2);
6313}
6314
6315SDValue ARMTargetLowering::LowerSET_FPMODE(SDValue Op,
6316 SelectionDAG &DAG) const {
6317 SDLoc DL(Op);
6318 SDValue Chain = Op->getOperand(0);
6319 SDValue Mode = Op->getOperand(1);
6320
6321 // Generate nodes to build:
6322 // FPSCR = (FPSCR & FPStatusBits) | (Mode & ~FPStatusBits)
6323 SDValue Ops[] = {Chain,
6324 DAG.getConstant(Intrinsic::arm_get_fpscr, DL, MVT::i32)};
6325 SDValue FPSCR =
6326 DAG.getNode(ISD::INTRINSIC_W_CHAIN, DL, {MVT::i32, MVT::Other}, Ops);
6327 Chain = FPSCR.getValue(1);
6328 FPSCR = FPSCR.getValue(0);
6329
6330 SDValue FPSCRMasked =
6331 DAG.getNode(ISD::AND, DL, MVT::i32, FPSCR,
6332 DAG.getConstant(ARM::FPStatusBits, DL, MVT::i32));
6333 SDValue InputMasked =
6334 DAG.getNode(ISD::AND, DL, MVT::i32, Mode,
6335 DAG.getConstant(~ARM::FPStatusBits, DL, MVT::i32));
6336 FPSCR = DAG.getNode(ISD::OR, DL, MVT::i32, FPSCRMasked, InputMasked);
6337
6338 SDValue Ops2[] = {
6339 Chain, DAG.getConstant(Intrinsic::arm_set_fpscr, DL, MVT::i32), FPSCR};
6340 return DAG.getNode(ISD::INTRINSIC_VOID, DL, MVT::Other, Ops2);
6341}
6342
6343SDValue ARMTargetLowering::LowerRESET_FPMODE(SDValue Op,
6344 SelectionDAG &DAG) const {
6345 SDLoc DL(Op);
6346 SDValue Chain = Op->getOperand(0);
6347
6348 // To get the default FP mode all control bits are cleared:
6349 // FPSCR = FPSCR & (FPStatusBits | FPReservedBits)
6350 SDValue Ops[] = {Chain,
6351 DAG.getConstant(Intrinsic::arm_get_fpscr, DL, MVT::i32)};
6352 SDValue FPSCR =
6353 DAG.getNode(ISD::INTRINSIC_W_CHAIN, DL, {MVT::i32, MVT::Other}, Ops);
6354 Chain = FPSCR.getValue(1);
6355 FPSCR = FPSCR.getValue(0);
6356
6357 SDValue FPSCRMasked = DAG.getNode(
6358 ISD::AND, DL, MVT::i32, FPSCR,
6360 SDValue Ops2[] = {Chain,
6361 DAG.getConstant(Intrinsic::arm_set_fpscr, DL, MVT::i32),
6362 FPSCRMasked};
6363 return DAG.getNode(ISD::INTRINSIC_VOID, DL, MVT::Other, Ops2);
6364}
6365
6367 const ARMSubtarget *ST) {
6368 SDLoc dl(N);
6369 EVT VT = N->getValueType(0);
6370 if (VT.isVector() && ST->hasNEON()) {
6371
6372 // Compute the least significant set bit: LSB = X & -X
6373 SDValue X = N->getOperand(0);
6374 SDValue NX = DAG.getNode(ISD::SUB, dl, VT, getZeroVector(VT, DAG, dl), X);
6375 SDValue LSB = DAG.getNode(ISD::AND, dl, VT, X, NX);
6376
6378
6379 if (ElemTy == MVT::i8) {
6380 // Compute with: cttz(x) = ctpop(lsb - 1)
6381 SDValue One = DAG.getNode(ARMISD::VMOVIMM, dl, VT,
6382 DAG.getTargetConstant(1, dl, ElemTy));
6383 SDValue Bits = DAG.getNode(ISD::SUB, dl, VT, LSB, One);
6384 return DAG.getNode(ISD::CTPOP, dl, VT, Bits);
6385 }
6386
6387 if ((ElemTy == MVT::i16 || ElemTy == MVT::i32) &&
6388 (N->getOpcode() == ISD::CTTZ_ZERO_POISON)) {
6389 // Compute with: cttz(x) = (width - 1) - ctlz(lsb), if x != 0
6390 unsigned NumBits = ElemTy.getSizeInBits();
6391 SDValue WidthMinus1 =
6392 DAG.getNode(ARMISD::VMOVIMM, dl, VT,
6393 DAG.getTargetConstant(NumBits - 1, dl, ElemTy));
6394 SDValue CTLZ = DAG.getNode(ISD::CTLZ, dl, VT, LSB);
6395 return DAG.getNode(ISD::SUB, dl, VT, WidthMinus1, CTLZ);
6396 }
6397
6398 // Compute with: cttz(x) = ctpop(lsb - 1)
6399
6400 // Compute LSB - 1.
6401 SDValue Bits;
6402 if (ElemTy == MVT::i64) {
6403 // Load constant 0xffff'ffff'ffff'ffff to register.
6404 SDValue FF = DAG.getNode(ARMISD::VMOVIMM, dl, VT,
6405 DAG.getTargetConstant(0x1eff, dl, MVT::i32));
6406 Bits = DAG.getNode(ISD::ADD, dl, VT, LSB, FF);
6407 } else {
6408 SDValue One = DAG.getNode(ARMISD::VMOVIMM, dl, VT,
6409 DAG.getTargetConstant(1, dl, ElemTy));
6410 Bits = DAG.getNode(ISD::SUB, dl, VT, LSB, One);
6411 }
6412 return DAG.getNode(ISD::CTPOP, dl, VT, Bits);
6413 }
6414
6415 if (!ST->hasV6T2Ops())
6416 return SDValue();
6417
6418 SDValue rbit = DAG.getNode(ISD::BITREVERSE, dl, VT, N->getOperand(0));
6419 return DAG.getNode(ISD::CTLZ, dl, VT, rbit);
6420}
6421
6423 const ARMSubtarget *ST) {
6424 EVT VT = N->getValueType(0);
6425 SDLoc DL(N);
6426
6427 assert(ST->hasNEON() && "Custom ctpop lowering requires NEON.");
6428 assert((VT == MVT::v1i64 || VT == MVT::v2i64 || VT == MVT::v2i32 ||
6429 VT == MVT::v4i32 || VT == MVT::v4i16 || VT == MVT::v8i16) &&
6430 "Unexpected type for custom ctpop lowering");
6431
6432 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
6433 EVT VT8Bit = VT.is64BitVector() ? MVT::v8i8 : MVT::v16i8;
6434 SDValue Res = DAG.getBitcast(VT8Bit, N->getOperand(0));
6435 Res = DAG.getNode(ISD::CTPOP, DL, VT8Bit, Res);
6436
6437 // Widen v8i8/v16i8 CTPOP result to VT by repeatedly widening pairwise adds.
6438 unsigned EltSize = 8;
6439 unsigned NumElts = VT.is64BitVector() ? 8 : 16;
6440 while (EltSize != VT.getScalarSizeInBits()) {
6442 Ops.push_back(DAG.getConstant(Intrinsic::arm_neon_vpaddlu, DL,
6443 TLI.getPointerTy(DAG.getDataLayout())));
6444 Ops.push_back(Res);
6445
6446 EltSize *= 2;
6447 NumElts /= 2;
6448 MVT WidenVT = MVT::getVectorVT(MVT::getIntegerVT(EltSize), NumElts);
6449 Res = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, DL, WidenVT, Ops);
6450 }
6451
6452 return Res;
6453}
6454
6455/// Getvshiftimm - Check if this is a valid build_vector for the immediate
6456/// operand of a vector shift operation, where all the elements of the
6457/// build_vector must have the same constant integer value.
6458static bool getVShiftImm(SDValue Op, unsigned ElementBits, int64_t &Cnt) {
6459 // Ignore bit_converts.
6460 while (Op.getOpcode() == ISD::BITCAST)
6461 Op = Op.getOperand(0);
6463 APInt SplatBits, SplatUndef;
6464 unsigned SplatBitSize;
6465 bool HasAnyUndefs;
6466 if (!BVN ||
6467 !BVN->isConstantSplat(SplatBits, SplatUndef, SplatBitSize, HasAnyUndefs,
6468 ElementBits) ||
6469 SplatBitSize > ElementBits)
6470 return false;
6471 Cnt = SplatBits.getSExtValue();
6472 return true;
6473}
6474
6475/// isVShiftLImm - Check if this is a valid build_vector for the immediate
6476/// operand of a vector shift left operation. That value must be in the range:
6477/// 0 <= Value < ElementBits for a left shift; or
6478/// 0 <= Value <= ElementBits for a long left shift.
6479static bool isVShiftLImm(SDValue Op, EVT VT, bool isLong, int64_t &Cnt) {
6480 assert(VT.isVector() && "vector shift count is not a vector type");
6481 int64_t ElementBits = VT.getScalarSizeInBits();
6482 if (!getVShiftImm(Op, ElementBits, Cnt))
6483 return false;
6484 return (Cnt >= 0 && (isLong ? Cnt - 1 : Cnt) < ElementBits);
6485}
6486
6487/// isVShiftRImm - Check if this is a valid build_vector for the immediate
6488/// operand of a vector shift right operation. For a shift opcode, the value
6489/// is positive, but for an intrinsic the value count must be negative. The
6490/// absolute value must be in the range:
6491/// 1 <= |Value| <= ElementBits for a right shift; or
6492/// 1 <= |Value| <= ElementBits/2 for a narrow right shift.
6493static bool isVShiftRImm(SDValue Op, EVT VT, bool isNarrow, bool isIntrinsic,
6494 int64_t &Cnt) {
6495 assert(VT.isVector() && "vector shift count is not a vector type");
6496 int64_t ElementBits = VT.getScalarSizeInBits();
6497 if (!getVShiftImm(Op, ElementBits, Cnt))
6498 return false;
6499 if (!isIntrinsic)
6500 return (Cnt >= 1 && Cnt <= (isNarrow ? ElementBits / 2 : ElementBits));
6501 if (Cnt >= -(isNarrow ? ElementBits / 2 : ElementBits) && Cnt <= -1) {
6502 Cnt = -Cnt;
6503 return true;
6504 }
6505 return false;
6506}
6507
6509 const ARMSubtarget *ST) {
6510 EVT VT = N->getValueType(0);
6511 SDLoc dl(N);
6512 int64_t Cnt;
6513
6514 if (!VT.isVector())
6515 return SDValue();
6516
6517 // We essentially have two forms here. Shift by an immediate and shift by a
6518 // vector register (there are also shift by a gpr, but that is just handled
6519 // with a tablegen pattern). We cannot easily match shift by an immediate in
6520 // tablegen so we do that here and generate a VSHLIMM/VSHRsIMM/VSHRuIMM.
6521 // For shifting by a vector, we don't have VSHR, only VSHL (which can be
6522 // signed or unsigned, and a negative shift indicates a shift right).
6523 if (N->getOpcode() == ISD::SHL) {
6524 if (isVShiftLImm(N->getOperand(1), VT, false, Cnt))
6525 return DAG.getNode(ARMISD::VSHLIMM, dl, VT, N->getOperand(0),
6526 DAG.getConstant(Cnt, dl, MVT::i32));
6527 return DAG.getNode(ARMISD::VSHLu, dl, VT, N->getOperand(0),
6528 N->getOperand(1));
6529 }
6530
6531 assert((N->getOpcode() == ISD::SRA || N->getOpcode() == ISD::SRL) &&
6532 "unexpected vector shift opcode");
6533
6534 if (isVShiftRImm(N->getOperand(1), VT, false, false, Cnt)) {
6535 unsigned VShiftOpc =
6536 (N->getOpcode() == ISD::SRA ? ARMISD::VSHRsIMM : ARMISD::VSHRuIMM);
6537 return DAG.getNode(VShiftOpc, dl, VT, N->getOperand(0),
6538 DAG.getConstant(Cnt, dl, MVT::i32));
6539 }
6540
6541 // Other right shifts we don't have operations for (we use a shift left by a
6542 // negative number).
6543 EVT ShiftVT = N->getOperand(1).getValueType();
6544 SDValue NegatedCount = DAG.getNode(
6545 ISD::SUB, dl, ShiftVT, getZeroVector(ShiftVT, DAG, dl), N->getOperand(1));
6546 unsigned VShiftOpc =
6547 (N->getOpcode() == ISD::SRA ? ARMISD::VSHLs : ARMISD::VSHLu);
6548 return DAG.getNode(VShiftOpc, dl, VT, N->getOperand(0), NegatedCount);
6549}
6550
6552 const ARMSubtarget *ST) {
6553 EVT VT = N->getValueType(0);
6554 SDLoc dl(N);
6555
6556 // We can get here for a node like i32 = ISD::SHL i32, i64
6557 if (VT != MVT::i64)
6558 return SDValue();
6559
6560 assert((N->getOpcode() == ISD::SRL || N->getOpcode() == ISD::SRA ||
6561 N->getOpcode() == ISD::SHL) &&
6562 "Unknown shift to lower!");
6563
6564 unsigned ShOpc = N->getOpcode();
6565 if (ST->hasMVEIntegerOps()) {
6566 SDValue ShAmt = N->getOperand(1);
6567 unsigned ShPartsOpc = ARMISD::LSLL;
6569
6570 // If the shift amount is greater than 32 or has a greater bitwidth than 64
6571 // then do the default optimisation
6572 if ((!Con && ShAmt->getValueType(0).getSizeInBits() > 64) ||
6573 (Con && (Con->getAPIntValue() == 0 || Con->getAPIntValue().uge(32))))
6574 return SDValue();
6575
6576 // Extract the lower 32 bits of the shift amount if it's not an i32
6577 if (ShAmt->getValueType(0) != MVT::i32)
6578 ShAmt = DAG.getZExtOrTrunc(ShAmt, dl, MVT::i32);
6579
6580 if (ShOpc == ISD::SRL) {
6581 if (!Con)
6582 // There is no t2LSRLr instruction so negate and perform an lsll if the
6583 // shift amount is in a register, emulating a right shift.
6584 ShAmt = DAG.getNode(ISD::SUB, dl, MVT::i32,
6585 DAG.getConstant(0, dl, MVT::i32), ShAmt);
6586 else
6587 // Else generate an lsrl on the immediate shift amount
6588 ShPartsOpc = ARMISD::LSRL;
6589 } else if (ShOpc == ISD::SRA)
6590 ShPartsOpc = ARMISD::ASRL;
6591
6592 // Split Lower/Upper 32 bits of the destination/source
6593 SDValue Lo, Hi;
6594 std::tie(Lo, Hi) =
6595 DAG.SplitScalar(N->getOperand(0), dl, MVT::i32, MVT::i32);
6596 // Generate the shift operation as computed above
6597 Lo = DAG.getNode(ShPartsOpc, dl, DAG.getVTList(MVT::i32, MVT::i32), Lo, Hi,
6598 ShAmt);
6599 // The upper 32 bits come from the second return value of lsll
6600 Hi = SDValue(Lo.getNode(), 1);
6601 return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Lo, Hi);
6602 }
6603
6604 // We only lower SRA, SRL of 1 here, all others use generic lowering.
6605 if (!isOneConstant(N->getOperand(1)) || N->getOpcode() == ISD::SHL)
6606 return SDValue();
6607
6608 // If we are in thumb mode, we don't have RRX.
6609 if (ST->isThumb1Only())
6610 return SDValue();
6611
6612 // Okay, we have a 64-bit SRA or SRL of 1. Lower this to an RRX expr.
6613 SDValue Lo, Hi;
6614 std::tie(Lo, Hi) = DAG.SplitScalar(N->getOperand(0), dl, MVT::i32, MVT::i32);
6615
6616 // First, build a LSRS1/ASRS1 op, which shifts the top part by one and
6617 // captures the shifted out bit into a carry flag.
6618 unsigned Opc = N->getOpcode() == ISD::SRL ? ARMISD::LSRS1 : ARMISD::ASRS1;
6619 Hi = DAG.getNode(Opc, dl, DAG.getVTList(MVT::i32, FlagsVT), Hi);
6620
6621 // The low part is an ARMISD::RRX operand, which shifts the carry in.
6622 Lo = DAG.getNode(ARMISD::RRX, dl, MVT::i32, Lo, Hi.getValue(1));
6623
6624 // Merge the pieces into a single i64 value.
6625 return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Lo, Hi);
6626}
6627
6629 const ARMSubtarget *ST) {
6630 bool Invert = false;
6631 bool Swap = false;
6632 unsigned Opc = ARMCC::AL;
6633
6634 SDValue Op0 = Op.getOperand(0);
6635 SDValue Op1 = Op.getOperand(1);
6636 SDValue CC = Op.getOperand(2);
6637 EVT VT = Op.getValueType();
6638 ISD::CondCode SetCCOpcode = cast<CondCodeSDNode>(CC)->get();
6639 SDLoc dl(Op);
6640
6641 EVT CmpVT;
6642 if (ST->hasNEON())
6644 else {
6645 assert(ST->hasMVEIntegerOps() &&
6646 "No hardware support for integer vector comparison!");
6647
6648 if (Op.getValueType().getVectorElementType() != MVT::i1)
6649 return SDValue();
6650
6651 // Make sure we expand floating point setcc to scalar if we do not have
6652 // mve.fp, so that we can handle them from there.
6653 if (Op0.getValueType().isFloatingPoint() && !ST->hasMVEFloatOps())
6654 return SDValue();
6655
6656 CmpVT = VT;
6657 }
6658
6659 if (Op0.getValueType().getVectorElementType() == MVT::i64 &&
6660 (SetCCOpcode == ISD::SETEQ || SetCCOpcode == ISD::SETNE)) {
6661 // Special-case integer 64-bit equality comparisons. They aren't legal,
6662 // but they can be lowered with a few vector instructions.
6663 unsigned CmpElements = CmpVT.getVectorNumElements() * 2;
6664 EVT SplitVT = EVT::getVectorVT(*DAG.getContext(), MVT::i32, CmpElements);
6665 SDValue CastOp0 = DAG.getNode(ISD::BITCAST, dl, SplitVT, Op0);
6666 SDValue CastOp1 = DAG.getNode(ISD::BITCAST, dl, SplitVT, Op1);
6667 SDValue Cmp = DAG.getNode(ISD::SETCC, dl, SplitVT, CastOp0, CastOp1,
6668 DAG.getCondCode(ISD::SETEQ));
6669 SDValue Reversed = DAG.getNode(ARMISD::VREV64, dl, SplitVT, Cmp);
6670 SDValue Merged = DAG.getNode(ISD::AND, dl, SplitVT, Cmp, Reversed);
6671 Merged = DAG.getNode(ISD::BITCAST, dl, CmpVT, Merged);
6672 if (SetCCOpcode == ISD::SETNE)
6673 Merged = DAG.getNOT(dl, Merged, CmpVT);
6674 Merged = DAG.getSExtOrTrunc(Merged, dl, VT);
6675 return Merged;
6676 }
6677
6678 if (CmpVT.getVectorElementType() == MVT::i64)
6679 // 64-bit comparisons are not legal in general.
6680 return SDValue();
6681
6682 if (Op1.getValueType().isFloatingPoint()) {
6683 switch (SetCCOpcode) {
6684 default: llvm_unreachable("Illegal FP comparison");
6685 case ISD::SETUNE:
6686 case ISD::SETNE:
6687 if (ST->hasMVEFloatOps()) {
6688 Opc = ARMCC::NE; break;
6689 } else {
6690 Invert = true; [[fallthrough]];
6691 }
6692 case ISD::SETOEQ:
6693 case ISD::SETEQ: Opc = ARMCC::EQ; break;
6694 case ISD::SETOLT:
6695 case ISD::SETLT: Swap = true; [[fallthrough]];
6696 case ISD::SETOGT:
6697 case ISD::SETGT: Opc = ARMCC::GT; break;
6698 case ISD::SETOLE:
6699 case ISD::SETLE: Swap = true; [[fallthrough]];
6700 case ISD::SETOGE:
6701 case ISD::SETGE: Opc = ARMCC::GE; break;
6702 case ISD::SETUGE: Swap = true; [[fallthrough]];
6703 case ISD::SETULE: Invert = true; Opc = ARMCC::GT; break;
6704 case ISD::SETUGT: Swap = true; [[fallthrough]];
6705 case ISD::SETULT: Invert = true; Opc = ARMCC::GE; break;
6706 case ISD::SETUEQ: Invert = true; [[fallthrough]];
6707 case ISD::SETONE: {
6708 // Expand this to (OLT | OGT).
6709 SDValue TmpOp0 = DAG.getNode(ARMISD::VCMP, dl, CmpVT, Op1, Op0,
6710 DAG.getConstant(ARMCC::GT, dl, MVT::i32));
6711 SDValue TmpOp1 = DAG.getNode(ARMISD::VCMP, dl, CmpVT, Op0, Op1,
6712 DAG.getConstant(ARMCC::GT, dl, MVT::i32));
6713 SDValue Result = DAG.getNode(ISD::OR, dl, CmpVT, TmpOp0, TmpOp1);
6714 if (Invert)
6715 Result = DAG.getNOT(dl, Result, VT);
6716 return Result;
6717 }
6718 case ISD::SETUO: Invert = true; [[fallthrough]];
6719 case ISD::SETO: {
6720 // Expand this to (OLT | OGE).
6721 SDValue TmpOp0 = DAG.getNode(ARMISD::VCMP, dl, CmpVT, Op1, Op0,
6722 DAG.getConstant(ARMCC::GT, dl, MVT::i32));
6723 SDValue TmpOp1 = DAG.getNode(ARMISD::VCMP, dl, CmpVT, Op0, Op1,
6724 DAG.getConstant(ARMCC::GE, dl, MVT::i32));
6725 SDValue Result = DAG.getNode(ISD::OR, dl, CmpVT, TmpOp0, TmpOp1);
6726 if (Invert)
6727 Result = DAG.getNOT(dl, Result, VT);
6728 return Result;
6729 }
6730 }
6731 } else {
6732 // Integer comparisons.
6733 switch (SetCCOpcode) {
6734 default: llvm_unreachable("Illegal integer comparison");
6735 case ISD::SETNE:
6736 if (ST->hasMVEIntegerOps()) {
6737 Opc = ARMCC::NE; break;
6738 } else {
6739 Invert = true; [[fallthrough]];
6740 }
6741 case ISD::SETEQ: Opc = ARMCC::EQ; break;
6742 case ISD::SETLT: Swap = true; [[fallthrough]];
6743 case ISD::SETGT: Opc = ARMCC::GT; break;
6744 case ISD::SETLE: Swap = true; [[fallthrough]];
6745 case ISD::SETGE: Opc = ARMCC::GE; break;
6746 case ISD::SETULT: Swap = true; [[fallthrough]];
6747 case ISD::SETUGT: Opc = ARMCC::HI; break;
6748 case ISD::SETULE: Swap = true; [[fallthrough]];
6749 case ISD::SETUGE: Opc = ARMCC::HS; break;
6750 }
6751
6752 // Detect VTST (Vector Test Bits) = icmp ne (and (op0, op1), zero).
6753 if (ST->hasNEON() && Opc == ARMCC::EQ) {
6754 SDValue AndOp;
6756 AndOp = Op0;
6757 else if (ISD::isBuildVectorAllZeros(Op0.getNode()))
6758 AndOp = Op1;
6759
6760 // Ignore bitconvert.
6761 if (AndOp.getNode() && AndOp.getOpcode() == ISD::BITCAST)
6762 AndOp = AndOp.getOperand(0);
6763
6764 if (AndOp.getNode() && AndOp.getOpcode() == ISD::AND) {
6765 Op0 = DAG.getNode(ISD::BITCAST, dl, CmpVT, AndOp.getOperand(0));
6766 Op1 = DAG.getNode(ISD::BITCAST, dl, CmpVT, AndOp.getOperand(1));
6767 SDValue Result = DAG.getNode(ARMISD::VTST, dl, CmpVT, Op0, Op1);
6768 if (!Invert)
6769 Result = DAG.getNOT(dl, Result, VT);
6770 return Result;
6771 }
6772 }
6773 }
6774
6775 if (Swap)
6776 std::swap(Op0, Op1);
6777
6778 // If one of the operands is a constant vector zero, attempt to fold the
6779 // comparison to a specialized compare-against-zero form.
6781 (Opc == ARMCC::GE || Opc == ARMCC::GT || Opc == ARMCC::EQ ||
6782 Opc == ARMCC::NE)) {
6783 if (Opc == ARMCC::GE)
6784 Opc = ARMCC::LE;
6785 else if (Opc == ARMCC::GT)
6786 Opc = ARMCC::LT;
6787 std::swap(Op0, Op1);
6788 }
6789
6790 SDValue Result;
6792 (Opc == ARMCC::GE || Opc == ARMCC::GT || Opc == ARMCC::LE ||
6793 Opc == ARMCC::LT || Opc == ARMCC::NE || Opc == ARMCC::EQ))
6794 Result = DAG.getNode(ARMISD::VCMPZ, dl, CmpVT, Op0,
6795 DAG.getConstant(Opc, dl, MVT::i32));
6796 else
6797 Result = DAG.getNode(ARMISD::VCMP, dl, CmpVT, Op0, Op1,
6798 DAG.getConstant(Opc, dl, MVT::i32));
6799
6800 Result = DAG.getSExtOrTrunc(Result, dl, VT);
6801
6802 if (Invert)
6803 Result = DAG.getNOT(dl, Result, VT);
6804
6805 return Result;
6806}
6807
6809 SDValue LHS = Op.getOperand(0);
6810 SDValue RHS = Op.getOperand(1);
6811
6812 assert(LHS.getSimpleValueType().isInteger() && "SETCCCARRY is integer only.");
6813
6814 SDValue Carry = Op.getOperand(2);
6815 SDValue Cond = Op.getOperand(3);
6816 SDLoc DL(Op);
6817
6818 // ARMISD::SUBE expects a carry not a borrow like ISD::USUBO_CARRY so we
6819 // have to invert the carry first.
6820 SDValue InvCarry = valueToCarryFlag(Carry, DAG, true);
6821
6822 SDVTList VTs = DAG.getVTList(LHS.getValueType(), MVT::i32);
6823 SDValue Cmp = DAG.getNode(ARMISD::SUBE, DL, VTs, LHS, RHS, InvCarry);
6824
6825 SDValue FVal = DAG.getConstant(0, DL, MVT::i32);
6826 SDValue TVal = DAG.getConstant(1, DL, MVT::i32);
6827 SDValue ARMcc = DAG.getConstant(
6828 IntCCToARMCC(cast<CondCodeSDNode>(Cond)->get()), DL, MVT::i32);
6829 return DAG.getNode(ARMISD::CMOV, DL, Op.getValueType(), FVal, TVal, ARMcc,
6830 Cmp.getValue(1));
6831}
6832
6833/// isVMOVModifiedImm - Check if the specified splat value corresponds to a
6834/// valid vector constant for a NEON or MVE instruction with a "modified
6835/// immediate" operand (e.g., VMOV). If so, return the encoded value.
6836static SDValue isVMOVModifiedImm(uint64_t SplatBits, uint64_t SplatUndef,
6837 unsigned SplatBitSize, SelectionDAG &DAG,
6838 const SDLoc &dl, EVT &VT, EVT VectorVT,
6839 VMOVModImmType type) {
6840 unsigned OpCmode, Imm;
6841 bool is128Bits = VectorVT.is128BitVector();
6842
6843 // SplatBitSize is set to the smallest size that splats the vector, so a
6844 // zero vector will always have SplatBitSize == 8. However, NEON modified
6845 // immediate instructions others than VMOV do not support the 8-bit encoding
6846 // of a zero vector, and the default encoding of zero is supposed to be the
6847 // 32-bit version.
6848 if (SplatBits == 0)
6849 SplatBitSize = 32;
6850
6851 switch (SplatBitSize) {
6852 case 8:
6853 if (type != VMOVModImm)
6854 return SDValue();
6855 // Any 1-byte value is OK. Op=0, Cmode=1110.
6856 assert((SplatBits & ~0xff) == 0 && "one byte splat value is too big");
6857 OpCmode = 0xe;
6858 Imm = SplatBits;
6859 VT = is128Bits ? MVT::v16i8 : MVT::v8i8;
6860 break;
6861
6862 case 16:
6863 // NEON's 16-bit VMOV supports splat values where only one byte is nonzero.
6864 VT = is128Bits ? MVT::v8i16 : MVT::v4i16;
6865 if ((SplatBits & ~0xff) == 0) {
6866 // Value = 0x00nn: Op=x, Cmode=100x.
6867 OpCmode = 0x8;
6868 Imm = SplatBits;
6869 break;
6870 }
6871 if ((SplatBits & ~0xff00) == 0) {
6872 // Value = 0xnn00: Op=x, Cmode=101x.
6873 OpCmode = 0xa;
6874 Imm = SplatBits >> 8;
6875 break;
6876 }
6877 return SDValue();
6878
6879 case 32:
6880 // NEON's 32-bit VMOV supports splat values where:
6881 // * only one byte is nonzero, or
6882 // * the least significant byte is 0xff and the second byte is nonzero, or
6883 // * the least significant 2 bytes are 0xff and the third is nonzero.
6884 VT = is128Bits ? MVT::v4i32 : MVT::v2i32;
6885 if ((SplatBits & ~0xff) == 0) {
6886 // Value = 0x000000nn: Op=x, Cmode=000x.
6887 OpCmode = 0;
6888 Imm = SplatBits;
6889 break;
6890 }
6891 if ((SplatBits & ~0xff00) == 0) {
6892 // Value = 0x0000nn00: Op=x, Cmode=001x.
6893 OpCmode = 0x2;
6894 Imm = SplatBits >> 8;
6895 break;
6896 }
6897 if ((SplatBits & ~0xff0000) == 0) {
6898 // Value = 0x00nn0000: Op=x, Cmode=010x.
6899 OpCmode = 0x4;
6900 Imm = SplatBits >> 16;
6901 break;
6902 }
6903 if ((SplatBits & ~0xff000000) == 0) {
6904 // Value = 0xnn000000: Op=x, Cmode=011x.
6905 OpCmode = 0x6;
6906 Imm = SplatBits >> 24;
6907 break;
6908 }
6909
6910 // cmode == 0b1100 and cmode == 0b1101 are not supported for VORR or VBIC
6911 if (type == OtherModImm) return SDValue();
6912
6913 if ((SplatBits & ~0xffff) == 0 &&
6914 ((SplatBits | SplatUndef) & 0xff) == 0xff) {
6915 // Value = 0x0000nnff: Op=x, Cmode=1100.
6916 OpCmode = 0xc;
6917 Imm = SplatBits >> 8;
6918 break;
6919 }
6920
6921 // cmode == 0b1101 is not supported for MVE VMVN
6922 if (type == MVEVMVNModImm)
6923 return SDValue();
6924
6925 if ((SplatBits & ~0xffffff) == 0 &&
6926 ((SplatBits | SplatUndef) & 0xffff) == 0xffff) {
6927 // Value = 0x00nnffff: Op=x, Cmode=1101.
6928 OpCmode = 0xd;
6929 Imm = SplatBits >> 16;
6930 break;
6931 }
6932
6933 // Note: there are a few 32-bit splat values (specifically: 00ffff00,
6934 // ff000000, ff0000ff, and ffff00ff) that are valid for VMOV.I64 but not
6935 // VMOV.I32. A (very) minor optimization would be to replicate the value
6936 // and fall through here to test for a valid 64-bit splat. But, then the
6937 // caller would also need to check and handle the change in size.
6938 return SDValue();
6939
6940 case 64: {
6941 if (type != VMOVModImm)
6942 return SDValue();
6943 // NEON has a 64-bit VMOV splat where each byte is either 0 or 0xff.
6944 uint64_t BitMask = 0xff;
6945 unsigned ImmMask = 1;
6946 Imm = 0;
6947 for (int ByteNum = 0; ByteNum < 8; ++ByteNum) {
6948 if (((SplatBits | SplatUndef) & BitMask) == BitMask) {
6949 Imm |= ImmMask;
6950 } else if ((SplatBits & BitMask) != 0) {
6951 return SDValue();
6952 }
6953 BitMask <<= 8;
6954 ImmMask <<= 1;
6955 }
6956
6957 // Op=1, Cmode=1110.
6958 OpCmode = 0x1e;
6959 VT = is128Bits ? MVT::v2i64 : MVT::v1i64;
6960 break;
6961 }
6962
6963 default:
6964 llvm_unreachable("unexpected size for isVMOVModifiedImm");
6965 }
6966
6967 unsigned EncodedVal = ARM_AM::createVMOVModImm(OpCmode, Imm);
6968 return DAG.getTargetConstant(EncodedVal, dl, MVT::i32);
6969}
6970
6971SDValue ARMTargetLowering::LowerConstantFP(SDValue Op, SelectionDAG &DAG,
6972 const ARMSubtarget *ST) const {
6973 EVT VT = Op.getValueType();
6974 bool IsDouble = (VT == MVT::f64);
6975 ConstantFPSDNode *CFP = cast<ConstantFPSDNode>(Op);
6976 const APFloat &FPVal = CFP->getValueAPF();
6977
6978 // Prevent floating-point constants from using literal loads
6979 // when execute-only is enabled.
6980 if (ST->genExecuteOnly()) {
6981 // We shouldn't trigger this for v6m execute-only
6982 assert((!ST->isThumb1Only() || ST->hasV8MBaselineOps()) &&
6983 "Unexpected architecture");
6984
6985 // If we can represent the constant as an immediate, don't lower it
6986 if (isFPImmLegal(FPVal, VT))
6987 return Op;
6988 // Otherwise, construct as integer, and move to float register
6989 APInt INTVal = FPVal.bitcastToAPInt();
6990 SDLoc DL(CFP);
6991 switch (VT.getSimpleVT().SimpleTy) {
6992 default:
6993 llvm_unreachable("Unknown floating point type!");
6994 break;
6995 case MVT::f64: {
6996 SDValue Lo = DAG.getConstant(INTVal.trunc(32), DL, MVT::i32);
6997 SDValue Hi = DAG.getConstant(INTVal.lshr(32).trunc(32), DL, MVT::i32);
6998 return DAG.getNode(ARMISD::VMOVDRR, DL, MVT::f64, Lo, Hi);
6999 }
7000 case MVT::f32:
7001 return DAG.getNode(ARMISD::VMOVSR, DL, VT,
7002 DAG.getConstant(INTVal, DL, MVT::i32));
7003 }
7004 }
7005
7006 if (!ST->hasVFP3Base())
7007 return SDValue();
7008
7009 // Use the default (constant pool) lowering for double constants when we have
7010 // an SP-only FPU
7011 if (IsDouble && !Subtarget->hasFP64())
7012 return SDValue();
7013
7014 // Try splatting with a VMOV.f32...
7015 int ImmVal = IsDouble ? ARM_AM::getFP64Imm(FPVal) : ARM_AM::getFP32Imm(FPVal);
7016
7017 if (ImmVal != -1) {
7018 if (IsDouble || !ST->useNEONForSinglePrecisionFP()) {
7019 // We have code in place to select a valid ConstantFP already, no need to
7020 // do any mangling.
7021 return Op;
7022 }
7023
7024 // It's a float and we are trying to use NEON operations where
7025 // possible. Lower it to a splat followed by an extract.
7026 SDLoc DL(Op);
7027 SDValue NewVal = DAG.getTargetConstant(ImmVal, DL, MVT::i32);
7028 SDValue VecConstant = DAG.getNode(ARMISD::VMOVFPIMM, DL, MVT::v2f32,
7029 NewVal);
7030 return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::f32, VecConstant,
7031 DAG.getConstant(0, DL, MVT::i32));
7032 }
7033
7034 // The rest of our options are NEON only, make sure that's allowed before
7035 // proceeding..
7036 if (!ST->hasNEON() || (!IsDouble && !ST->useNEONForSinglePrecisionFP()))
7037 return SDValue();
7038
7039 EVT VMovVT;
7040 uint64_t iVal = FPVal.bitcastToAPInt().getZExtValue();
7041
7042 // It wouldn't really be worth bothering for doubles except for one very
7043 // important value, which does happen to match: 0.0. So make sure we don't do
7044 // anything stupid.
7045 if (IsDouble && (iVal & 0xffffffff) != (iVal >> 32))
7046 return SDValue();
7047
7048 // Try a VMOV.i32 (FIXME: i8, i16, or i64 could work too).
7049 SDValue NewVal = isVMOVModifiedImm(iVal & 0xffffffffU, 0, 32, DAG, SDLoc(Op),
7050 VMovVT, VT, VMOVModImm);
7051 if (NewVal != SDValue()) {
7052 SDLoc DL(Op);
7053 SDValue VecConstant = DAG.getNode(ARMISD::VMOVIMM, DL, VMovVT,
7054 NewVal);
7055 if (IsDouble)
7056 return DAG.getNode(ISD::BITCAST, DL, MVT::f64, VecConstant);
7057
7058 // It's a float: cast and extract a vector element.
7059 SDValue VecFConstant = DAG.getNode(ISD::BITCAST, DL, MVT::v2f32,
7060 VecConstant);
7061 return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::f32, VecFConstant,
7062 DAG.getConstant(0, DL, MVT::i32));
7063 }
7064
7065 // Finally, try a VMVN.i32
7066 NewVal = isVMOVModifiedImm(~iVal & 0xffffffffU, 0, 32, DAG, SDLoc(Op), VMovVT,
7067 VT, VMVNModImm);
7068 if (NewVal != SDValue()) {
7069 SDLoc DL(Op);
7070 SDValue VecConstant = DAG.getNode(ARMISD::VMVNIMM, DL, VMovVT, NewVal);
7071
7072 if (IsDouble)
7073 return DAG.getNode(ISD::BITCAST, DL, MVT::f64, VecConstant);
7074
7075 // It's a float: cast and extract a vector element.
7076 SDValue VecFConstant = DAG.getNode(ISD::BITCAST, DL, MVT::v2f32,
7077 VecConstant);
7078 return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::f32, VecFConstant,
7079 DAG.getConstant(0, DL, MVT::i32));
7080 }
7081
7082 return SDValue();
7083}
7084
7085// check if an VEXT instruction can handle the shuffle mask when the
7086// vector sources of the shuffle are the same.
7087static bool isSingletonVEXTMask(ArrayRef<int> M, EVT VT, unsigned &Imm) {
7088 unsigned NumElts = VT.getVectorNumElements();
7089
7090 // Assume that the first shuffle index is not UNDEF. Fail if it is.
7091 if (M[0] < 0)
7092 return false;
7093
7094 Imm = M[0];
7095
7096 // If this is a VEXT shuffle, the immediate value is the index of the first
7097 // element. The other shuffle indices must be the successive elements after
7098 // the first one.
7099 unsigned ExpectedElt = Imm;
7100 for (unsigned i = 1; i < NumElts; ++i) {
7101 // Increment the expected index. If it wraps around, just follow it
7102 // back to index zero and keep going.
7103 ++ExpectedElt;
7104 if (ExpectedElt == NumElts)
7105 ExpectedElt = 0;
7106
7107 if (M[i] < 0) continue; // ignore UNDEF indices
7108 if (ExpectedElt != static_cast<unsigned>(M[i]))
7109 return false;
7110 }
7111
7112 return true;
7113}
7114
7115static bool isVEXTMask(ArrayRef<int> M, EVT VT,
7116 bool &ReverseVEXT, unsigned &Imm) {
7117 unsigned NumElts = VT.getVectorNumElements();
7118 ReverseVEXT = false;
7119
7120 // Assume that the first shuffle index is not UNDEF. Fail if it is.
7121 if (M[0] < 0)
7122 return false;
7123
7124 Imm = M[0];
7125
7126 // If this is a VEXT shuffle, the immediate value is the index of the first
7127 // element. The other shuffle indices must be the successive elements after
7128 // the first one.
7129 unsigned ExpectedElt = Imm;
7130 for (unsigned i = 1; i < NumElts; ++i) {
7131 // Increment the expected index. If it wraps around, it may still be
7132 // a VEXT but the source vectors must be swapped.
7133 ExpectedElt += 1;
7134 if (ExpectedElt == NumElts * 2) {
7135 ExpectedElt = 0;
7136 ReverseVEXT = true;
7137 }
7138
7139 if (M[i] < 0) continue; // ignore UNDEF indices
7140 if (ExpectedElt != static_cast<unsigned>(M[i]))
7141 return false;
7142 }
7143
7144 // Adjust the index value if the source operands will be swapped.
7145 if (ReverseVEXT)
7146 Imm -= NumElts;
7147
7148 return true;
7149}
7150
7151static bool isVTBLMask(ArrayRef<int> M, EVT VT) {
7152 // We can handle <8 x i8> vector shuffles. If the index in the mask is out of
7153 // range, then 0 is placed into the resulting vector. So pretty much any mask
7154 // of 8 elements can work here.
7155 return VT == MVT::v8i8 && M.size() == 8;
7156}
7157
7158static unsigned SelectPairHalf(unsigned Elements, ArrayRef<int> Mask,
7159 unsigned Index) {
7160 if (Mask.size() == Elements * 2)
7161 return Index / Elements;
7162 return Mask[Index] == 0 ? 0 : 1;
7163}
7164
7165// Checks whether the shuffle mask represents a vector transpose (VTRN) by
7166// checking that pairs of elements in the shuffle mask represent the same index
7167// in each vector, incrementing the expected index by 2 at each step.
7168// e.g. For v1,v2 of type v4i32 a valid shuffle mask is: [0, 4, 2, 6]
7169// v1={a,b,c,d} => x=shufflevector v1, v2 shufflemask => x={a,e,c,g}
7170// v2={e,f,g,h}
7171// WhichResult gives the offset for each element in the mask based on which
7172// of the two results it belongs to.
7173//
7174// The transpose can be represented either as:
7175// result1 = shufflevector v1, v2, result1_shuffle_mask
7176// result2 = shufflevector v1, v2, result2_shuffle_mask
7177// where v1/v2 and the shuffle masks have the same number of elements
7178// (here WhichResult (see below) indicates which result is being checked)
7179//
7180// or as:
7181// results = shufflevector v1, v2, shuffle_mask
7182// where both results are returned in one vector and the shuffle mask has twice
7183// as many elements as v1/v2 (here WhichResult will always be 0 if true) here we
7184// want to check the low half and high half of the shuffle mask as if it were
7185// the other case
7186static bool isVTRNMask(ArrayRef<int> M, EVT VT, unsigned &WhichResult) {
7187 unsigned EltSz = VT.getScalarSizeInBits();
7188 if (EltSz == 64)
7189 return false;
7190
7191 unsigned NumElts = VT.getVectorNumElements();
7192 if ((M.size() != NumElts && M.size() != NumElts * 2) || NumElts % 2 != 0)
7193 return false;
7194
7195 // If the mask is twice as long as the input vector then we need to check the
7196 // upper and lower parts of the mask with a matching value for WhichResult
7197 // FIXME: A mask with only even values will be rejected in case the first
7198 // element is undefined, e.g. [-1, 4, 2, 6] will be rejected, because only
7199 // M[0] is used to determine WhichResult
7200 for (unsigned i = 0; i < M.size(); i += NumElts) {
7201 WhichResult = SelectPairHalf(NumElts, M, i);
7202 for (unsigned j = 0; j < NumElts; j += 2) {
7203 if ((M[i+j] >= 0 && (unsigned) M[i+j] != j + WhichResult) ||
7204 (M[i+j+1] >= 0 && (unsigned) M[i+j+1] != j + NumElts + WhichResult))
7205 return false;
7206 }
7207 }
7208
7209 if (M.size() == NumElts*2)
7210 WhichResult = 0;
7211
7212 return true;
7213}
7214
7215/// isVTRN_v_undef_Mask - Special case of isVTRNMask for canonical form of
7216/// "vector_shuffle v, v", i.e., "vector_shuffle v, undef".
7217/// Mask is e.g., <0, 0, 2, 2> instead of <0, 4, 2, 6>.
7218static bool isVTRN_v_undef_Mask(ArrayRef<int> M, EVT VT, unsigned &WhichResult){
7219 unsigned EltSz = VT.getScalarSizeInBits();
7220 if (EltSz == 64)
7221 return false;
7222
7223 unsigned NumElts = VT.getVectorNumElements();
7224 if ((M.size() != NumElts && M.size() != NumElts * 2) || NumElts % 2 != 0)
7225 return false;
7226
7227 for (unsigned i = 0; i < M.size(); i += NumElts) {
7228 WhichResult = SelectPairHalf(NumElts, M, i);
7229 for (unsigned j = 0; j < NumElts; j += 2) {
7230 if ((M[i+j] >= 0 && (unsigned) M[i+j] != j + WhichResult) ||
7231 (M[i+j+1] >= 0 && (unsigned) M[i+j+1] != j + WhichResult))
7232 return false;
7233 }
7234 }
7235
7236 if (M.size() == NumElts*2)
7237 WhichResult = 0;
7238
7239 return true;
7240}
7241
7242// Checks whether the shuffle mask represents a vector unzip (VUZP) by checking
7243// that the mask elements are either all even and in steps of size 2 or all odd
7244// and in steps of size 2.
7245// e.g. For v1,v2 of type v4i32 a valid shuffle mask is: [0, 2, 4, 6]
7246// v1={a,b,c,d} => x=shufflevector v1, v2 shufflemask => x={a,c,e,g}
7247// v2={e,f,g,h}
7248// Requires similar checks to that of isVTRNMask with
7249// respect the how results are returned.
7250static bool isVUZPMask(ArrayRef<int> M, EVT VT, unsigned &WhichResult) {
7251 unsigned EltSz = VT.getScalarSizeInBits();
7252 if (EltSz == 64)
7253 return false;
7254
7255 unsigned NumElts = VT.getVectorNumElements();
7256 if (M.size() != NumElts && M.size() != NumElts*2)
7257 return false;
7258
7259 for (unsigned i = 0; i < M.size(); i += NumElts) {
7260 WhichResult = SelectPairHalf(NumElts, M, i);
7261 for (unsigned j = 0; j < NumElts; ++j) {
7262 if (M[i+j] >= 0 && (unsigned) M[i+j] != 2 * j + WhichResult)
7263 return false;
7264 }
7265 }
7266
7267 if (M.size() == NumElts*2)
7268 WhichResult = 0;
7269
7270 // VUZP.32 for 64-bit vectors is a pseudo-instruction alias for VTRN.32.
7271 if (VT.is64BitVector() && EltSz == 32)
7272 return false;
7273
7274 return true;
7275}
7276
7277/// isVUZP_v_undef_Mask - Special case of isVUZPMask for canonical form of
7278/// "vector_shuffle v, v", i.e., "vector_shuffle v, undef".
7279/// Mask is e.g., <0, 2, 0, 2> instead of <0, 2, 4, 6>,
7280static bool isVUZP_v_undef_Mask(ArrayRef<int> M, EVT VT, unsigned &WhichResult){
7281 unsigned EltSz = VT.getScalarSizeInBits();
7282 if (EltSz == 64)
7283 return false;
7284
7285 unsigned NumElts = VT.getVectorNumElements();
7286 if (M.size() != NumElts && M.size() != NumElts*2)
7287 return false;
7288
7289 unsigned Half = NumElts / 2;
7290 for (unsigned i = 0; i < M.size(); i += NumElts) {
7291 WhichResult = SelectPairHalf(NumElts, M, i);
7292 for (unsigned j = 0; j < NumElts; j += Half) {
7293 unsigned Idx = WhichResult;
7294 for (unsigned k = 0; k < Half; ++k) {
7295 int MIdx = M[i + j + k];
7296 if (MIdx >= 0 && (unsigned) MIdx != Idx)
7297 return false;
7298 Idx += 2;
7299 }
7300 }
7301 }
7302
7303 if (M.size() == NumElts*2)
7304 WhichResult = 0;
7305
7306 // VUZP.32 for 64-bit vectors is a pseudo-instruction alias for VTRN.32.
7307 if (VT.is64BitVector() && EltSz == 32)
7308 return false;
7309
7310 return true;
7311}
7312
7313// Checks whether the shuffle mask represents a vector zip (VZIP) by checking
7314// that pairs of elements of the shufflemask represent the same index in each
7315// vector incrementing sequentially through the vectors.
7316// e.g. For v1,v2 of type v4i32 a valid shuffle mask is: [0, 4, 1, 5]
7317// v1={a,b,c,d} => x=shufflevector v1, v2 shufflemask => x={a,e,b,f}
7318// v2={e,f,g,h}
7319// Requires similar checks to that of isVTRNMask with respect the how results
7320// are returned.
7321static bool isVZIPMask(ArrayRef<int> M, EVT VT, unsigned &WhichResult) {
7322 unsigned EltSz = VT.getScalarSizeInBits();
7323 if (EltSz == 64)
7324 return false;
7325
7326 unsigned NumElts = VT.getVectorNumElements();
7327 if ((M.size() != NumElts && M.size() != NumElts * 2) || NumElts % 2 != 0)
7328 return false;
7329
7330 for (unsigned i = 0; i < M.size(); i += NumElts) {
7331 WhichResult = SelectPairHalf(NumElts, M, i);
7332 unsigned Idx = WhichResult * NumElts / 2;
7333 for (unsigned j = 0; j < NumElts; j += 2) {
7334 if ((M[i+j] >= 0 && (unsigned) M[i+j] != Idx) ||
7335 (M[i+j+1] >= 0 && (unsigned) M[i+j+1] != Idx + NumElts))
7336 return false;
7337 Idx += 1;
7338 }
7339 }
7340
7341 if (M.size() == NumElts*2)
7342 WhichResult = 0;
7343
7344 // VZIP.32 for 64-bit vectors is a pseudo-instruction alias for VTRN.32.
7345 if (VT.is64BitVector() && EltSz == 32)
7346 return false;
7347
7348 return true;
7349}
7350
7351/// isVZIP_v_undef_Mask - Special case of isVZIPMask for canonical form of
7352/// "vector_shuffle v, v", i.e., "vector_shuffle v, undef".
7353/// Mask is e.g., <0, 0, 1, 1> instead of <0, 4, 1, 5>.
7354static bool isVZIP_v_undef_Mask(ArrayRef<int> M, EVT VT, unsigned &WhichResult){
7355 unsigned EltSz = VT.getScalarSizeInBits();
7356 if (EltSz == 64)
7357 return false;
7358
7359 unsigned NumElts = VT.getVectorNumElements();
7360 if ((M.size() != NumElts && M.size() != NumElts * 2) || NumElts % 2 != 0)
7361 return false;
7362
7363 for (unsigned i = 0; i < M.size(); i += NumElts) {
7364 WhichResult = SelectPairHalf(NumElts, M, i);
7365 unsigned Idx = WhichResult * NumElts / 2;
7366 for (unsigned j = 0; j < NumElts; j += 2) {
7367 if ((M[i+j] >= 0 && (unsigned) M[i+j] != Idx) ||
7368 (M[i+j+1] >= 0 && (unsigned) M[i+j+1] != Idx))
7369 return false;
7370 Idx += 1;
7371 }
7372 }
7373
7374 if (M.size() == NumElts*2)
7375 WhichResult = 0;
7376
7377 // VZIP.32 for 64-bit vectors is a pseudo-instruction alias for VTRN.32.
7378 if (VT.is64BitVector() && EltSz == 32)
7379 return false;
7380
7381 return true;
7382}
7383
7384/// Check if \p ShuffleMask is a NEON two-result shuffle (VZIP, VUZP, VTRN),
7385/// and return the corresponding ARMISD opcode if it is, or 0 if it isn't.
7386static unsigned isNEONTwoResultShuffleMask(ArrayRef<int> ShuffleMask, EVT VT,
7387 unsigned &WhichResult,
7388 bool &isV_UNDEF) {
7389 isV_UNDEF = false;
7390 if (isVTRNMask(ShuffleMask, VT, WhichResult))
7391 return ARMISD::VTRN;
7392 if (isVUZPMask(ShuffleMask, VT, WhichResult))
7393 return ARMISD::VUZP;
7394 if (isVZIPMask(ShuffleMask, VT, WhichResult))
7395 return ARMISD::VZIP;
7396
7397 isV_UNDEF = true;
7398 if (isVTRN_v_undef_Mask(ShuffleMask, VT, WhichResult))
7399 return ARMISD::VTRN;
7400 if (isVUZP_v_undef_Mask(ShuffleMask, VT, WhichResult))
7401 return ARMISD::VUZP;
7402 if (isVZIP_v_undef_Mask(ShuffleMask, VT, WhichResult))
7403 return ARMISD::VZIP;
7404
7405 return 0;
7406}
7407
7408/// \return true if this is a reverse operation on an vector.
7409static bool isReverseMask(ArrayRef<int> M, EVT VT) {
7410 unsigned NumElts = VT.getVectorNumElements();
7411 // Make sure the mask has the right size.
7412 if (NumElts != M.size())
7413 return false;
7414
7415 // Look for <15, ..., 3, -1, 1, 0>.
7416 for (unsigned i = 0; i != NumElts; ++i)
7417 if (M[i] >= 0 && M[i] != (int) (NumElts - 1 - i))
7418 return false;
7419
7420 return true;
7421}
7422
7423static bool isTruncMask(ArrayRef<int> M, EVT VT, bool Top, bool SingleSource) {
7424 unsigned NumElts = VT.getVectorNumElements();
7425 // Make sure the mask has the right size.
7426 if (NumElts != M.size() || (VT != MVT::v8i16 && VT != MVT::v16i8))
7427 return false;
7428
7429 // Half-width truncation patterns (e.g. v4i32 -> v8i16):
7430 // !Top && SingleSource: <0, 2, 4, 6, 0, 2, 4, 6>
7431 // !Top && !SingleSource: <0, 2, 4, 6, 8, 10, 12, 14>
7432 // Top && SingleSource: <1, 3, 5, 7, 1, 3, 5, 7>
7433 // Top && !SingleSource: <1, 3, 5, 7, 9, 11, 13, 15>
7434 int Ofs = Top ? 1 : 0;
7435 int Upper = SingleSource ? 0 : NumElts;
7436 for (int i = 0, e = NumElts / 2; i != e; ++i) {
7437 if (M[i] >= 0 && M[i] != (i * 2) + Ofs)
7438 return false;
7439 if (M[i + e] >= 0 && M[i + e] != (i * 2) + Ofs + Upper)
7440 return false;
7441 }
7442 return true;
7443}
7444
7445static bool isVMOVNMask(ArrayRef<int> M, EVT VT, bool Top, bool SingleSource) {
7446 unsigned NumElts = VT.getVectorNumElements();
7447 // Make sure the mask has the right size.
7448 if (NumElts != M.size() || (VT != MVT::v8i16 && VT != MVT::v16i8))
7449 return false;
7450
7451 // If Top
7452 // Look for <0, N, 2, N+2, 4, N+4, ..>.
7453 // This inserts Input2 into Input1
7454 // else if not Top
7455 // Look for <0, N+1, 2, N+3, 4, N+5, ..>
7456 // This inserts Input1 into Input2
7457 unsigned Offset = Top ? 0 : 1;
7458 unsigned N = SingleSource ? 0 : NumElts;
7459 for (unsigned i = 0; i < NumElts; i += 2) {
7460 if (M[i] >= 0 && M[i] != (int)i)
7461 return false;
7462 if (M[i + 1] >= 0 && M[i + 1] != (int)(N + i + Offset))
7463 return false;
7464 }
7465
7466 return true;
7467}
7468
7469static bool isVMOVNTruncMask(ArrayRef<int> M, EVT ToVT, bool rev) {
7470 unsigned NumElts = ToVT.getVectorNumElements();
7471 if (NumElts != M.size())
7472 return false;
7473
7474 // Test if the Trunc can be convertible to a VMOVN with this shuffle. We are
7475 // looking for patterns of:
7476 // !rev: 0 N/2 1 N/2+1 2 N/2+2 ...
7477 // rev: N/2 0 N/2+1 1 N/2+2 2 ...
7478
7479 unsigned Off0 = rev ? NumElts / 2 : 0;
7480 unsigned Off1 = rev ? 0 : NumElts / 2;
7481 for (unsigned i = 0; i < NumElts; i += 2) {
7482 if (M[i] >= 0 && M[i] != (int)(Off0 + i / 2))
7483 return false;
7484 if (M[i + 1] >= 0 && M[i + 1] != (int)(Off1 + i / 2))
7485 return false;
7486 }
7487
7488 return true;
7489}
7490
7491// Reconstruct an MVE VCVT from a BuildVector of scalar fptrunc, all extracted
7492// from a pair of inputs. For example:
7493// BUILDVECTOR(FP_ROUND(EXTRACT_ELT(X, 0),
7494// FP_ROUND(EXTRACT_ELT(Y, 0),
7495// FP_ROUND(EXTRACT_ELT(X, 1),
7496// FP_ROUND(EXTRACT_ELT(Y, 1), ...)
7498 const ARMSubtarget *ST) {
7499 assert(BV.getOpcode() == ISD::BUILD_VECTOR && "Unknown opcode!");
7500 if (!ST->hasMVEFloatOps())
7501 return SDValue();
7502
7503 SDLoc dl(BV);
7504 EVT VT = BV.getValueType();
7505 if (VT != MVT::v8f16)
7506 return SDValue();
7507
7508 // We are looking for a buildvector of fptrunc elements, where all the
7509 // elements are interleavingly extracted from two sources. Check the first two
7510 // items are valid enough and extract some info from them (they are checked
7511 // properly in the loop below).
7512 if (BV.getOperand(0).getOpcode() != ISD::FP_ROUND ||
7515 return SDValue();
7516 if (BV.getOperand(1).getOpcode() != ISD::FP_ROUND ||
7519 return SDValue();
7520 SDValue Op0 = BV.getOperand(0).getOperand(0).getOperand(0);
7521 SDValue Op1 = BV.getOperand(1).getOperand(0).getOperand(0);
7522 if (Op0.getValueType() != MVT::v4f32 || Op1.getValueType() != MVT::v4f32)
7523 return SDValue();
7524
7525 // Check all the values in the BuildVector line up with our expectations.
7526 for (unsigned i = 1; i < 4; i++) {
7527 auto Check = [](SDValue Trunc, SDValue Op, unsigned Idx) {
7528 return Trunc.getOpcode() == ISD::FP_ROUND &&
7530 Trunc.getOperand(0).getOperand(0) == Op &&
7531 Trunc.getOperand(0).getConstantOperandVal(1) == Idx;
7532 };
7533 if (!Check(BV.getOperand(i * 2 + 0), Op0, i))
7534 return SDValue();
7535 if (!Check(BV.getOperand(i * 2 + 1), Op1, i))
7536 return SDValue();
7537 }
7538
7539 SDValue N1 = DAG.getNode(ARMISD::VCVTN, dl, VT, DAG.getUNDEF(VT), Op0,
7540 DAG.getConstant(0, dl, MVT::i32));
7541 return DAG.getNode(ARMISD::VCVTN, dl, VT, N1, Op1,
7542 DAG.getConstant(1, dl, MVT::i32));
7543}
7544
7545// Reconstruct an MVE VCVT from a BuildVector of scalar fpext, all extracted
7546// from a single input on alternating lanes. For example:
7547// BUILDVECTOR(FP_ROUND(EXTRACT_ELT(X, 0),
7548// FP_ROUND(EXTRACT_ELT(X, 2),
7549// FP_ROUND(EXTRACT_ELT(X, 4), ...)
7551 const ARMSubtarget *ST) {
7552 assert(BV.getOpcode() == ISD::BUILD_VECTOR && "Unknown opcode!");
7553 if (!ST->hasMVEFloatOps())
7554 return SDValue();
7555
7556 SDLoc dl(BV);
7557 EVT VT = BV.getValueType();
7558 if (VT != MVT::v4f32)
7559 return SDValue();
7560
7561 // We are looking for a buildvector of fptext elements, where all the
7562 // elements are alternating lanes from a single source. For example <0,2,4,6>
7563 // or <1,3,5,7>. Check the first two items are valid enough and extract some
7564 // info from them (they are checked properly in the loop below).
7565 if (BV.getOperand(0).getOpcode() != ISD::FP_EXTEND ||
7567 return SDValue();
7568 SDValue Op0 = BV.getOperand(0).getOperand(0).getOperand(0);
7570 if (Op0.getValueType() != MVT::v8f16 || (Offset != 0 && Offset != 1))
7571 return SDValue();
7572
7573 // Check all the values in the BuildVector line up with our expectations.
7574 for (unsigned i = 1; i < 4; i++) {
7575 auto Check = [](SDValue Trunc, SDValue Op, unsigned Idx) {
7576 return Trunc.getOpcode() == ISD::FP_EXTEND &&
7578 Trunc.getOperand(0).getOperand(0) == Op &&
7579 Trunc.getOperand(0).getConstantOperandVal(1) == Idx;
7580 };
7581 if (!Check(BV.getOperand(i), Op0, 2 * i + Offset))
7582 return SDValue();
7583 }
7584
7585 return DAG.getNode(ARMISD::VCVTL, dl, VT, Op0,
7586 DAG.getConstant(Offset, dl, MVT::i32));
7587}
7588
7589// If N is an integer constant that can be moved into a register in one
7590// instruction, return an SDValue of such a constant (will become a MOV
7591// instruction). Otherwise return null.
7593 const ARMSubtarget *ST, const SDLoc &dl) {
7594 uint64_t Val;
7595 if (!isa<ConstantSDNode>(N))
7596 return SDValue();
7597 Val = N->getAsZExtVal();
7598
7599 if (ST->isThumb1Only()) {
7600 if (Val <= 255 || ~Val <= 255)
7601 return DAG.getConstant(Val, dl, MVT::i32);
7602 } else {
7603 if (ARM_AM::getSOImmVal(Val) != -1 || ARM_AM::getSOImmVal(~Val) != -1)
7604 return DAG.getConstant(Val, dl, MVT::i32);
7605 }
7606 return SDValue();
7607}
7608
7610 const ARMSubtarget *ST) {
7611 SDLoc dl(Op);
7612 EVT VT = Op.getValueType();
7613
7614 assert(ST->hasMVEIntegerOps() && "LowerBUILD_VECTOR_i1 called without MVE!");
7615
7616 unsigned NumElts = VT.getVectorNumElements();
7617 unsigned BoolMask;
7618 unsigned BitsPerBool;
7619 if (NumElts == 2) {
7620 BitsPerBool = 8;
7621 BoolMask = 0xff;
7622 } else if (NumElts == 4) {
7623 BitsPerBool = 4;
7624 BoolMask = 0xf;
7625 } else if (NumElts == 8) {
7626 BitsPerBool = 2;
7627 BoolMask = 0x3;
7628 } else if (NumElts == 16) {
7629 BitsPerBool = 1;
7630 BoolMask = 0x1;
7631 } else
7632 return SDValue();
7633
7634 // If this is a single value copied into all lanes (a splat), we can just sign
7635 // extend that single value
7636 SDValue FirstOp = Op.getOperand(0);
7637 if (!isa<ConstantSDNode>(FirstOp) &&
7638 llvm::all_of(llvm::drop_begin(Op->ops()), [&FirstOp](const SDUse &U) {
7639 return U.get().isUndef() || U.get() == FirstOp;
7640 })) {
7641 SDValue Ext = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, MVT::i32, FirstOp,
7642 DAG.getValueType(MVT::i1));
7643 return DAG.getNode(ARMISD::PREDICATE_CAST, dl, Op.getValueType(), Ext);
7644 }
7645
7646 // First create base with bits set where known
7647 unsigned Bits32 = 0;
7648 for (unsigned i = 0; i < NumElts; ++i) {
7649 SDValue V = Op.getOperand(i);
7650 if (!isa<ConstantSDNode>(V) && !V.isUndef())
7651 continue;
7652 bool BitSet = V.isUndef() ? false : V->getAsZExtVal();
7653 if (BitSet)
7654 Bits32 |= BoolMask << (i * BitsPerBool);
7655 }
7656
7657 // Add in unknown nodes
7658 SDValue Base = DAG.getNode(ARMISD::PREDICATE_CAST, dl, VT,
7659 DAG.getConstant(Bits32, dl, MVT::i32));
7660 for (unsigned i = 0; i < NumElts; ++i) {
7661 SDValue V = Op.getOperand(i);
7662 if (isa<ConstantSDNode>(V) || V.isUndef())
7663 continue;
7664 Base = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, VT, Base, V,
7665 DAG.getConstant(i, dl, MVT::i32));
7666 }
7667
7668 return Base;
7669}
7670
7672 const ARMSubtarget *ST) {
7673 if (!ST->hasMVEIntegerOps())
7674 return SDValue();
7675
7676 // We are looking for a buildvector where each element is Op[0] + i*N
7677 EVT VT = Op.getValueType();
7678 SDValue Op0 = Op.getOperand(0);
7679 unsigned NumElts = VT.getVectorNumElements();
7680
7681 // Get the increment value from operand 1
7682 SDValue Op1 = Op.getOperand(1);
7683 if (Op1.getOpcode() != ISD::ADD || Op1.getOperand(0) != Op0 ||
7685 return SDValue();
7686 unsigned N = Op1.getConstantOperandVal(1);
7687 if (N != 1 && N != 2 && N != 4 && N != 8)
7688 return SDValue();
7689
7690 // Check that each other operand matches
7691 for (unsigned I = 2; I < NumElts; I++) {
7692 SDValue OpI = Op.getOperand(I);
7693 if (OpI.getOpcode() != ISD::ADD || OpI.getOperand(0) != Op0 ||
7695 OpI.getConstantOperandVal(1) != I * N)
7696 return SDValue();
7697 }
7698
7699 SDLoc DL(Op);
7700 return DAG.getNode(ARMISD::VIDUP, DL, DAG.getVTList(VT, MVT::i32), Op0,
7701 DAG.getConstant(N, DL, MVT::i32));
7702}
7703
7704// Returns true if the operation N can be treated as qr instruction variant at
7705// operand Op.
7706static bool IsQRMVEInstruction(const SDNode *N, const SDNode *Op) {
7707 switch (N->getOpcode()) {
7708 case ISD::ADD:
7709 case ISD::MUL:
7710 case ISD::SADDSAT:
7711 case ISD::UADDSAT:
7712 case ISD::AVGFLOORS:
7713 case ISD::AVGFLOORU:
7714 return true;
7715 case ISD::SUB:
7716 case ISD::SSUBSAT:
7717 case ISD::USUBSAT:
7718 return N->getOperand(1).getNode() == Op;
7720 switch (N->getConstantOperandVal(0)) {
7721 case Intrinsic::arm_mve_add_predicated:
7722 case Intrinsic::arm_mve_mul_predicated:
7723 case Intrinsic::arm_mve_qadd_predicated:
7724 case Intrinsic::arm_mve_vhadd:
7725 case Intrinsic::arm_mve_hadd_predicated:
7726 case Intrinsic::arm_mve_vqdmulh:
7727 case Intrinsic::arm_mve_qdmulh_predicated:
7728 case Intrinsic::arm_mve_vqrdmulh:
7729 case Intrinsic::arm_mve_qrdmulh_predicated:
7730 case Intrinsic::arm_mve_vqdmull:
7731 case Intrinsic::arm_mve_vqdmull_predicated:
7732 return true;
7733 case Intrinsic::arm_mve_sub_predicated:
7734 case Intrinsic::arm_mve_qsub_predicated:
7735 case Intrinsic::arm_mve_vhsub:
7736 case Intrinsic::arm_mve_hsub_predicated:
7737 return N->getOperand(2).getNode() == Op;
7738 default:
7739 return false;
7740 }
7741 default:
7742 return false;
7743 }
7744}
7745
7746// If this is a case we can't handle, return null and let the default
7747// expansion code take care of it.
7748SDValue ARMTargetLowering::LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG,
7749 const ARMSubtarget *ST) const {
7750 BuildVectorSDNode *BVN = cast<BuildVectorSDNode>(Op.getNode());
7751 SDLoc dl(Op);
7752 EVT VT = Op.getValueType();
7753
7754 if (ST->hasMVEIntegerOps() && VT.getScalarSizeInBits() == 1)
7755 return LowerBUILD_VECTOR_i1(Op, DAG, ST);
7756
7757 if (SDValue R = LowerBUILD_VECTORToVIDUP(Op, DAG, ST))
7758 return R;
7759
7760 APInt SplatBits, SplatUndef;
7761 unsigned SplatBitSize;
7762 bool HasAnyUndefs;
7763 if (BVN->isConstantSplat(SplatBits, SplatUndef, SplatBitSize, HasAnyUndefs)) {
7764 if (SplatUndef.isAllOnes())
7765 return DAG.getUNDEF(VT);
7766
7767 // If all the users of this constant splat are qr instruction variants,
7768 // generate a vdup of the constant.
7769 if (ST->hasMVEIntegerOps() && VT.getScalarSizeInBits() == SplatBitSize &&
7770 (SplatBitSize == 8 || SplatBitSize == 16 || SplatBitSize == 32) &&
7771 all_of(BVN->users(),
7772 [BVN](const SDNode *U) { return IsQRMVEInstruction(U, BVN); })) {
7773 EVT DupVT = SplatBitSize == 32 ? MVT::v4i32
7774 : SplatBitSize == 16 ? MVT::v8i16
7775 : MVT::v16i8;
7776 SDValue Const = DAG.getConstant(SplatBits.getZExtValue(), dl, MVT::i32);
7777 SDValue VDup = DAG.getNode(ARMISD::VDUP, dl, DupVT, Const);
7778 return DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, VT, VDup);
7779 }
7780
7781 if ((ST->hasNEON() && SplatBitSize <= 64) ||
7782 (ST->hasMVEIntegerOps() && SplatBitSize <= 64)) {
7783 // Check if an immediate VMOV works.
7784 EVT VmovVT;
7785 SDValue Val =
7786 isVMOVModifiedImm(SplatBits.getZExtValue(), SplatUndef.getZExtValue(),
7787 SplatBitSize, DAG, dl, VmovVT, VT, VMOVModImm);
7788
7789 if (Val.getNode()) {
7790 SDValue Vmov = DAG.getNode(ARMISD::VMOVIMM, dl, VmovVT, Val);
7791 return DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, VT, Vmov);
7792 }
7793
7794 // Try an immediate VMVN.
7795 uint64_t NegatedImm = (~SplatBits).getZExtValue();
7796 Val = isVMOVModifiedImm(
7797 NegatedImm, SplatUndef.getZExtValue(), SplatBitSize, DAG, dl, VmovVT,
7798 VT, ST->hasMVEIntegerOps() ? MVEVMVNModImm : VMVNModImm);
7799 if (Val.getNode()) {
7800 SDValue Vmov = DAG.getNode(ARMISD::VMVNIMM, dl, VmovVT, Val);
7801 return DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, VT, Vmov);
7802 }
7803
7804 // Use vmov.f32 to materialize other v2f32 and v4f32 splats.
7805 if ((VT == MVT::v2f32 || VT == MVT::v4f32) && SplatBitSize == 32) {
7806 int ImmVal = ARM_AM::getFP32Imm(SplatBits);
7807 if (ImmVal != -1) {
7808 SDValue Val = DAG.getTargetConstant(ImmVal, dl, MVT::i32);
7809 return DAG.getNode(ARMISD::VMOVFPIMM, dl, VT, Val);
7810 }
7811 }
7812
7813 // If we are under MVE, generate a VDUP(constant), bitcast to the original
7814 // type.
7815 if (ST->hasMVEIntegerOps() &&
7816 (SplatBitSize == 8 || SplatBitSize == 16 || SplatBitSize == 32)) {
7817 EVT DupVT = SplatBitSize == 32 ? MVT::v4i32
7818 : SplatBitSize == 16 ? MVT::v8i16
7819 : MVT::v16i8;
7820 SDValue Const = DAG.getConstant(SplatBits.getZExtValue(), dl, MVT::i32);
7821 SDValue VDup = DAG.getNode(ARMISD::VDUP, dl, DupVT, Const);
7822 return DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, VT, VDup);
7823 }
7824 }
7825 }
7826
7827 // Scan through the operands to see if only one value is used.
7828 //
7829 // As an optimisation, even if more than one value is used it may be more
7830 // profitable to splat with one value then change some lanes.
7831 //
7832 // Heuristically we decide to do this if the vector has a "dominant" value,
7833 // defined as splatted to more than half of the lanes.
7834 unsigned NumElts = VT.getVectorNumElements();
7835 bool isOnlyLowElement = true;
7836 bool usesOnlyOneValue = true;
7837 bool hasDominantValue = false;
7838 bool isConstant = true;
7839
7840 // Map of the number of times a particular SDValue appears in the
7841 // element list.
7842 DenseMap<SDValue, unsigned> ValueCounts;
7843 SDValue Value;
7844 for (unsigned i = 0; i < NumElts; ++i) {
7845 SDValue V = Op.getOperand(i);
7846 if (V.isUndef())
7847 continue;
7848 if (i > 0)
7849 isOnlyLowElement = false;
7851 isConstant = false;
7852
7853 unsigned &Count = ValueCounts[V];
7854
7855 // Is this value dominant? (takes up more than half of the lanes)
7856 if (++Count > (NumElts / 2)) {
7857 hasDominantValue = true;
7858 Value = V;
7859 }
7860 }
7861 if (ValueCounts.size() != 1)
7862 usesOnlyOneValue = false;
7863 if (!Value.getNode() && !ValueCounts.empty())
7864 Value = ValueCounts.begin()->first;
7865
7866 if (ValueCounts.empty())
7867 return DAG.getUNDEF(VT);
7868
7869 // Loads are better lowered with insert_vector_elt/ARMISD::BUILD_VECTOR.
7870 // Keep going if we are hitting this case.
7871 if (isOnlyLowElement && !ISD::isNormalLoad(Value.getNode()) &&
7872 (VT != MVT::v8f16 || ST->hasFullFP16()))
7873 return DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VT, Value);
7874
7875 unsigned EltSize = VT.getScalarSizeInBits();
7876
7877 // Use VDUP for non-constant splats. For f32 constant splats, reduce to
7878 // i32 and try again.
7879 if (hasDominantValue && EltSize <= 32) {
7880 if (!isConstant) {
7881 SDValue N;
7882
7883 // If we are VDUPing a value that comes directly from a vector, that will
7884 // cause an unnecessary move to and from a GPR, where instead we could
7885 // just use VDUPLANE. We can only do this if the lane being extracted
7886 // is at a constant index, as the VDUP from lane instructions only have
7887 // constant-index forms.
7888 ConstantSDNode *constIndex;
7889 if (Value->getOpcode() == ISD::EXTRACT_VECTOR_ELT &&
7890 (constIndex = dyn_cast<ConstantSDNode>(Value->getOperand(1)))) {
7891 // We need to create a new undef vector to use for the VDUPLANE if the
7892 // size of the vector from which we get the value is different than the
7893 // size of the vector that we need to create. We will insert the element
7894 // such that the register coalescer will remove unnecessary copies.
7895 if (VT != Value->getOperand(0).getValueType()) {
7896 unsigned index = constIndex->getAPIntValue().getLimitedValue() %
7898 N = DAG.getNode(ARMISD::VDUPLANE, dl, VT,
7899 DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, VT, DAG.getUNDEF(VT),
7900 Value, DAG.getConstant(index, dl, MVT::i32)),
7901 DAG.getConstant(index, dl, MVT::i32));
7902 } else
7903 N = DAG.getNode(ARMISD::VDUPLANE, dl, VT,
7904 Value->getOperand(0), Value->getOperand(1));
7905 } else
7906 N = DAG.getNode(ARMISD::VDUP, dl, VT, Value);
7907
7908 if (!usesOnlyOneValue) {
7909 // The dominant value was splatted as 'N', but we now have to insert
7910 // all differing elements.
7911 for (unsigned I = 0; I < NumElts; ++I) {
7912 if (Op.getOperand(I) == Value)
7913 continue;
7915 Ops.push_back(N);
7916 Ops.push_back(Op.getOperand(I));
7917 Ops.push_back(DAG.getConstant(I, dl, MVT::i32));
7918 N = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, VT, Ops);
7919 }
7920 }
7921 return N;
7922 }
7925 MVT FVT = VT.getVectorElementType().getSimpleVT();
7926 assert(FVT == MVT::f32 || FVT == MVT::f16);
7927 MVT IVT = (FVT == MVT::f32) ? MVT::i32 : MVT::i16;
7928 for (unsigned i = 0; i < NumElts; ++i)
7929 Ops.push_back(DAG.getNode(ISD::BITCAST, dl, IVT,
7930 Op.getOperand(i)));
7931 EVT VecVT = EVT::getVectorVT(*DAG.getContext(), IVT, NumElts);
7932 SDValue Val = DAG.getBuildVector(VecVT, dl, Ops);
7933 Val = LowerBUILD_VECTOR(Val, DAG, ST);
7934 if (Val.getNode())
7935 return DAG.getNode(ISD::BITCAST, dl, VT, Val);
7936 }
7937 if (usesOnlyOneValue) {
7938 SDValue Val = IsSingleInstrConstant(Value, DAG, ST, dl);
7939 if (isConstant && Val.getNode())
7940 return DAG.getNode(ARMISD::VDUP, dl, VT, Val);
7941 }
7942 }
7943
7944 // If all elements are constants and the case above didn't get hit, fall back
7945 // to the default expansion, which will generate a load from the constant
7946 // pool.
7947 if (isConstant)
7948 return SDValue();
7949
7950 // Reconstruct the BUILDVECTOR to one of the legal shuffles (such as vext and
7951 // vmovn). Empirical tests suggest this is rarely worth it for vectors of
7952 // length <= 2.
7953 if (NumElts >= 4)
7954 if (SDValue shuffle = ReconstructShuffle(Op, DAG))
7955 return shuffle;
7956
7957 // Attempt to turn a buildvector of scalar fptrunc's or fpext's back into
7958 // VCVT's
7959 if (SDValue VCVT = LowerBuildVectorOfFPTrunc(Op, DAG, Subtarget))
7960 return VCVT;
7961 if (SDValue VCVT = LowerBuildVectorOfFPExt(Op, DAG, Subtarget))
7962 return VCVT;
7963
7964 if (ST->hasNEON() && VT.is128BitVector() && VT != MVT::v2f64 && VT != MVT::v4f32) {
7965 // If we haven't found an efficient lowering, try splitting a 128-bit vector
7966 // into two 64-bit vectors; we might discover a better way to lower it.
7967 SmallVector<SDValue, 64> Ops(Op->op_begin(), Op->op_begin() + NumElts);
7968 EVT ExtVT = VT.getVectorElementType();
7969 EVT HVT = EVT::getVectorVT(*DAG.getContext(), ExtVT, NumElts / 2);
7970 SDValue Lower = DAG.getBuildVector(HVT, dl, ArrayRef(&Ops[0], NumElts / 2));
7971 if (Lower.getOpcode() == ISD::BUILD_VECTOR)
7972 Lower = LowerBUILD_VECTOR(Lower, DAG, ST);
7973 SDValue Upper =
7974 DAG.getBuildVector(HVT, dl, ArrayRef(&Ops[NumElts / 2], NumElts / 2));
7975 if (Upper.getOpcode() == ISD::BUILD_VECTOR)
7976 Upper = LowerBUILD_VECTOR(Upper, DAG, ST);
7977 if (Lower && Upper)
7978 return DAG.getNode(ISD::CONCAT_VECTORS, dl, VT, Lower, Upper);
7979 }
7980
7981 // Vectors with 32- or 64-bit elements can be built by directly assigning
7982 // the subregisters. Lower it to an ARMISD::BUILD_VECTOR so the operands
7983 // will be legalized.
7984 if (EltSize >= 32) {
7985 // Do the expansion with floating-point types, since that is what the VFP
7986 // registers are defined to use, and since i64 is not legal.
7987 EVT EltVT = EVT::getFloatingPointVT(EltSize);
7988 EVT VecVT = EVT::getVectorVT(*DAG.getContext(), EltVT, NumElts);
7990 for (unsigned i = 0; i < NumElts; ++i)
7991 Ops.push_back(DAG.getNode(ISD::BITCAST, dl, EltVT, Op.getOperand(i)));
7992 SDValue Val = DAG.getNode(ARMISD::BUILD_VECTOR, dl, VecVT, Ops);
7993 return DAG.getNode(ISD::BITCAST, dl, VT, Val);
7994 }
7995
7996 // If all else fails, just use a sequence of INSERT_VECTOR_ELT when we
7997 // know the default expansion would otherwise fall back on something even
7998 // worse. For a vector with one or two non-undef values, that's
7999 // scalar_to_vector for the elements followed by a shuffle (provided the
8000 // shuffle is valid for the target) and materialization element by element
8001 // on the stack followed by a load for everything else.
8002 if ((!isConstant && !usesOnlyOneValue) ||
8003 (VT == MVT::v8f16 && !ST->hasFullFP16())) {
8004 SDValue Vec = DAG.getUNDEF(VT);
8005 for (unsigned i = 0 ; i < NumElts; ++i) {
8006 SDValue V = Op.getOperand(i);
8007 if (V.isUndef())
8008 continue;
8009 SDValue LaneIdx = DAG.getConstant(i, dl, MVT::i32);
8010 Vec = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, VT, Vec, V, LaneIdx);
8011 }
8012 return Vec;
8013 }
8014
8015 return SDValue();
8016}
8017
8018// Gather data to see if the operation can be modelled as a
8019// shuffle in combination with VEXTs.
8020SDValue ARMTargetLowering::ReconstructShuffle(SDValue Op,
8021 SelectionDAG &DAG) const {
8022 assert(Op.getOpcode() == ISD::BUILD_VECTOR && "Unknown opcode!");
8023 SDLoc dl(Op);
8024 EVT VT = Op.getValueType();
8025 unsigned NumElts = VT.getVectorNumElements();
8026
8027 struct ShuffleSourceInfo {
8028 SDValue Vec;
8029 unsigned MinElt = std::numeric_limits<unsigned>::max();
8030 unsigned MaxElt = 0;
8031
8032 // We may insert some combination of BITCASTs and VEXT nodes to force Vec to
8033 // be compatible with the shuffle we intend to construct. As a result
8034 // ShuffleVec will be some sliding window into the original Vec.
8035 SDValue ShuffleVec;
8036
8037 // Code should guarantee that element i in Vec starts at element "WindowBase
8038 // + i * WindowScale in ShuffleVec".
8039 int WindowBase = 0;
8040 int WindowScale = 1;
8041
8042 ShuffleSourceInfo(SDValue Vec) : Vec(Vec), ShuffleVec(Vec) {}
8043
8044 bool operator ==(SDValue OtherVec) { return Vec == OtherVec; }
8045 };
8046
8047 // First gather all vectors used as an immediate source for this BUILD_VECTOR
8048 // node.
8050 for (unsigned i = 0; i < NumElts; ++i) {
8051 SDValue V = Op.getOperand(i);
8052 if (V.isUndef())
8053 continue;
8054 else if (V.getOpcode() != ISD::EXTRACT_VECTOR_ELT) {
8055 // A shuffle can only come from building a vector from various
8056 // elements of other vectors.
8057 return SDValue();
8058 } else if (!isa<ConstantSDNode>(V.getOperand(1))) {
8059 // Furthermore, shuffles require a constant mask, whereas extractelts
8060 // accept variable indices.
8061 return SDValue();
8062 }
8063
8064 // Add this element source to the list if it's not already there.
8065 SDValue SourceVec = V.getOperand(0);
8066 auto Source = llvm::find(Sources, SourceVec);
8067 if (Source == Sources.end())
8068 Source = Sources.insert(Sources.end(), ShuffleSourceInfo(SourceVec));
8069
8070 // Update the minimum and maximum lane number seen.
8071 unsigned EltNo = V.getConstantOperandVal(1);
8072 Source->MinElt = std::min(Source->MinElt, EltNo);
8073 Source->MaxElt = std::max(Source->MaxElt, EltNo);
8074 }
8075
8076 // Currently only do something sane when at most two source vectors
8077 // are involved.
8078 if (Sources.size() > 2)
8079 return SDValue();
8080
8081 // Find out the smallest element size among result and two sources, and use
8082 // it as element size to build the shuffle_vector.
8083 EVT SmallestEltTy = VT.getVectorElementType();
8084 for (auto &Source : Sources) {
8085 EVT SrcEltTy = Source.Vec.getValueType().getVectorElementType();
8086 if (SrcEltTy.bitsLT(SmallestEltTy))
8087 SmallestEltTy = SrcEltTy;
8088 }
8089 unsigned ResMultiplier =
8090 VT.getScalarSizeInBits() / SmallestEltTy.getSizeInBits();
8091 NumElts = VT.getSizeInBits() / SmallestEltTy.getSizeInBits();
8092 EVT ShuffleVT = EVT::getVectorVT(*DAG.getContext(), SmallestEltTy, NumElts);
8093
8094 // If the source vector is too wide or too narrow, we may nevertheless be able
8095 // to construct a compatible shuffle either by concatenating it with UNDEF or
8096 // extracting a suitable range of elements.
8097 for (auto &Src : Sources) {
8098 EVT SrcVT = Src.ShuffleVec.getValueType();
8099
8100 uint64_t SrcVTSize = SrcVT.getFixedSizeInBits();
8101 uint64_t VTSize = VT.getFixedSizeInBits();
8102 if (SrcVTSize == VTSize)
8103 continue;
8104
8105 // This stage of the search produces a source with the same element type as
8106 // the original, but with a total width matching the BUILD_VECTOR output.
8107 EVT EltVT = SrcVT.getVectorElementType();
8108 unsigned NumSrcElts = VTSize / EltVT.getFixedSizeInBits();
8109 EVT DestVT = EVT::getVectorVT(*DAG.getContext(), EltVT, NumSrcElts);
8110
8111 if (SrcVTSize < VTSize) {
8112 if (2 * SrcVTSize != VTSize)
8113 return SDValue();
8114 // We can pad out the smaller vector for free, so if it's part of a
8115 // shuffle...
8116 Src.ShuffleVec =
8117 DAG.getNode(ISD::CONCAT_VECTORS, dl, DestVT, Src.ShuffleVec,
8118 DAG.getUNDEF(Src.ShuffleVec.getValueType()));
8119 continue;
8120 }
8121
8122 if (SrcVTSize != 2 * VTSize)
8123 return SDValue();
8124
8125 if (Src.MaxElt - Src.MinElt >= NumSrcElts) {
8126 // Span too large for a VEXT to cope
8127 return SDValue();
8128 }
8129
8130 if (Src.MinElt >= NumSrcElts) {
8131 // The extraction can just take the second half
8132 Src.ShuffleVec =
8133 DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, DestVT, Src.ShuffleVec,
8134 DAG.getConstant(NumSrcElts, dl, MVT::i32));
8135 Src.WindowBase = -NumSrcElts;
8136 } else if (Src.MaxElt < NumSrcElts) {
8137 // The extraction can just take the first half
8138 Src.ShuffleVec =
8139 DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, DestVT, Src.ShuffleVec,
8140 DAG.getConstant(0, dl, MVT::i32));
8141 } else {
8142 // An actual VEXT is needed
8143 SDValue VEXTSrc1 =
8144 DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, DestVT, Src.ShuffleVec,
8145 DAG.getConstant(0, dl, MVT::i32));
8146 SDValue VEXTSrc2 =
8147 DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, DestVT, Src.ShuffleVec,
8148 DAG.getConstant(NumSrcElts, dl, MVT::i32));
8149
8150 Src.ShuffleVec = DAG.getNode(ARMISD::VEXT, dl, DestVT, VEXTSrc1,
8151 VEXTSrc2,
8152 DAG.getConstant(Src.MinElt, dl, MVT::i32));
8153 Src.WindowBase = -Src.MinElt;
8154 }
8155 }
8156
8157 // Another possible incompatibility occurs from the vector element types. We
8158 // can fix this by bitcasting the source vectors to the same type we intend
8159 // for the shuffle.
8160 for (auto &Src : Sources) {
8161 EVT SrcEltTy = Src.ShuffleVec.getValueType().getVectorElementType();
8162 if (SrcEltTy == SmallestEltTy)
8163 continue;
8164 assert(ShuffleVT.getVectorElementType() == SmallestEltTy);
8165 Src.ShuffleVec = DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, ShuffleVT, Src.ShuffleVec);
8166 Src.WindowScale = SrcEltTy.getSizeInBits() / SmallestEltTy.getSizeInBits();
8167 Src.WindowBase *= Src.WindowScale;
8168 }
8169
8170 // Final check before we try to actually produce a shuffle.
8171 LLVM_DEBUG({
8172 for (auto Src : Sources)
8173 assert(Src.ShuffleVec.getValueType() == ShuffleVT);
8174 });
8175
8176 // The stars all align, our next step is to produce the mask for the shuffle.
8177 SmallVector<int, 8> Mask(ShuffleVT.getVectorNumElements(), -1);
8178 int BitsPerShuffleLane = ShuffleVT.getScalarSizeInBits();
8179 for (unsigned i = 0; i < VT.getVectorNumElements(); ++i) {
8180 SDValue Entry = Op.getOperand(i);
8181 if (Entry.isUndef())
8182 continue;
8183
8184 auto Src = llvm::find(Sources, Entry.getOperand(0));
8185 int EltNo = cast<ConstantSDNode>(Entry.getOperand(1))->getSExtValue();
8186
8187 // EXTRACT_VECTOR_ELT performs an implicit any_ext; BUILD_VECTOR an implicit
8188 // trunc. So only std::min(SrcBits, DestBits) actually get defined in this
8189 // segment.
8190 EVT OrigEltTy = Entry.getOperand(0).getValueType().getVectorElementType();
8191 int BitsDefined = std::min(OrigEltTy.getScalarSizeInBits(),
8192 VT.getScalarSizeInBits());
8193 int LanesDefined = BitsDefined / BitsPerShuffleLane;
8194
8195 // This source is expected to fill ResMultiplier lanes of the final shuffle,
8196 // starting at the appropriate offset.
8197 int *LaneMask = &Mask[i * ResMultiplier];
8198
8199 int ExtractBase = EltNo * Src->WindowScale + Src->WindowBase;
8200 ExtractBase += NumElts * (Src - Sources.begin());
8201 for (int j = 0; j < LanesDefined; ++j)
8202 LaneMask[j] = ExtractBase + j;
8203 }
8204
8205
8206 // We can't handle more than two sources. This should have already
8207 // been checked before this point.
8208 assert(Sources.size() <= 2 && "Too many sources!");
8209
8210 SDValue ShuffleOps[] = { DAG.getUNDEF(ShuffleVT), DAG.getUNDEF(ShuffleVT) };
8211 for (unsigned i = 0; i < Sources.size(); ++i)
8212 ShuffleOps[i] = Sources[i].ShuffleVec;
8213
8214 SDValue Shuffle = buildLegalVectorShuffle(ShuffleVT, dl, ShuffleOps[0],
8215 ShuffleOps[1], Mask, DAG);
8216 if (!Shuffle)
8217 return SDValue();
8218 return DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, VT, Shuffle);
8219}
8220
8222 OP_COPY = 0, // Copy, used for things like <u,u,u,3> to say it is <0,1,2,3>
8231 OP_VUZPL, // VUZP, left result
8232 OP_VUZPR, // VUZP, right result
8233 OP_VZIPL, // VZIP, left result
8234 OP_VZIPR, // VZIP, right result
8235 OP_VTRNL, // VTRN, left result
8236 OP_VTRNR // VTRN, right result
8237};
8238
8239static bool isLegalMVEShuffleOp(unsigned PFEntry) {
8240 unsigned OpNum = (PFEntry >> 26) & 0x0F;
8241 switch (OpNum) {
8242 case OP_COPY:
8243 case OP_VREV:
8244 case OP_VDUP0:
8245 case OP_VDUP1:
8246 case OP_VDUP2:
8247 case OP_VDUP3:
8248 return true;
8249 }
8250 return false;
8251}
8252
8253/// isShuffleMaskLegal - Targets can use this to indicate that they only
8254/// support *some* VECTOR_SHUFFLE operations, those with specific masks.
8255/// By default, if a target supports the VECTOR_SHUFFLE node, all mask values
8256/// are assumed to be legal.
8258 if (VT.getVectorNumElements() == 4 &&
8259 (VT.is128BitVector() || VT.is64BitVector())) {
8260 unsigned PFIndexes[4];
8261 for (unsigned i = 0; i != 4; ++i) {
8262 if (M[i] < 0)
8263 PFIndexes[i] = 8;
8264 else
8265 PFIndexes[i] = M[i];
8266 }
8267
8268 // Compute the index in the perfect shuffle table.
8269 unsigned PFTableIndex =
8270 PFIndexes[0]*9*9*9+PFIndexes[1]*9*9+PFIndexes[2]*9+PFIndexes[3];
8271 unsigned PFEntry = PerfectShuffleTable[PFTableIndex];
8272 unsigned Cost = (PFEntry >> 30);
8273
8274 if (Cost <= 4 && (Subtarget->hasNEON() || isLegalMVEShuffleOp(PFEntry)))
8275 return true;
8276 }
8277
8278 bool ReverseVEXT, isV_UNDEF;
8279 unsigned Imm, WhichResult;
8280
8281 unsigned EltSize = VT.getScalarSizeInBits();
8282 if (EltSize >= 32 ||
8284 ShuffleVectorInst::isIdentityMask(M, M.size()) ||
8285 isVREVMask(M, VT, 64) ||
8286 isVREVMask(M, VT, 32) ||
8287 isVREVMask(M, VT, 16))
8288 return true;
8289 else if (Subtarget->hasNEON() &&
8290 (isVEXTMask(M, VT, ReverseVEXT, Imm) ||
8291 isVTBLMask(M, VT) ||
8292 isNEONTwoResultShuffleMask(M, VT, WhichResult, isV_UNDEF)))
8293 return true;
8294 else if ((VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v16i8) &&
8295 isReverseMask(M, VT))
8296 return true;
8297 else if (Subtarget->hasMVEIntegerOps() &&
8298 (isVMOVNMask(M, VT, true, false) ||
8299 isVMOVNMask(M, VT, false, false) || isVMOVNMask(M, VT, true, true)))
8300 return true;
8301 else if (Subtarget->hasMVEIntegerOps() &&
8302 (isTruncMask(M, VT, false, false) ||
8303 isTruncMask(M, VT, false, true) ||
8304 isTruncMask(M, VT, true, false) || isTruncMask(M, VT, true, true)))
8305 return true;
8306 else
8307 return false;
8308}
8309
8310/// GeneratePerfectShuffle - Given an entry in the perfect-shuffle table, emit
8311/// the specified operations to build the shuffle.
8313 SDValue RHS, SelectionDAG &DAG,
8314 const SDLoc &dl) {
8315 unsigned OpNum = (PFEntry >> 26) & 0x0F;
8316 unsigned LHSID = (PFEntry >> 13) & ((1 << 13)-1);
8317 unsigned RHSID = (PFEntry >> 0) & ((1 << 13)-1);
8318
8319 if (OpNum == OP_COPY) {
8320 if (LHSID == (1*9+2)*9+3) return LHS;
8321 assert(LHSID == ((4*9+5)*9+6)*9+7 && "Illegal OP_COPY!");
8322 return RHS;
8323 }
8324
8325 SDValue OpLHS, OpRHS;
8326 OpLHS = GeneratePerfectShuffle(PerfectShuffleTable[LHSID], LHS, RHS, DAG, dl);
8327 OpRHS = GeneratePerfectShuffle(PerfectShuffleTable[RHSID], LHS, RHS, DAG, dl);
8328 EVT VT = OpLHS.getValueType();
8329
8330 switch (OpNum) {
8331 default: llvm_unreachable("Unknown shuffle opcode!");
8332 case OP_VREV:
8333 // VREV divides the vector in half and swaps within the half.
8334 if (VT.getScalarSizeInBits() == 32)
8335 return DAG.getNode(ARMISD::VREV64, dl, VT, OpLHS);
8336 // vrev <4 x i16> -> VREV32
8337 if (VT.getScalarSizeInBits() == 16)
8338 return DAG.getNode(ARMISD::VREV32, dl, VT, OpLHS);
8339 // vrev <4 x i8> -> VREV16
8340 assert(VT.getScalarSizeInBits() == 8);
8341 return DAG.getNode(ARMISD::VREV16, dl, VT, OpLHS);
8342 case OP_VDUP0:
8343 case OP_VDUP1:
8344 case OP_VDUP2:
8345 case OP_VDUP3:
8346 return DAG.getNode(ARMISD::VDUPLANE, dl, VT,
8347 OpLHS, DAG.getConstant(OpNum-OP_VDUP0, dl, MVT::i32));
8348 case OP_VEXT1:
8349 case OP_VEXT2:
8350 case OP_VEXT3:
8351 return DAG.getNode(ARMISD::VEXT, dl, VT,
8352 OpLHS, OpRHS,
8353 DAG.getConstant(OpNum - OP_VEXT1 + 1, dl, MVT::i32));
8354 case OP_VUZPL:
8355 case OP_VUZPR:
8356 return DAG.getNode(ARMISD::VUZP, dl, DAG.getVTList(VT, VT),
8357 OpLHS, OpRHS).getValue(OpNum-OP_VUZPL);
8358 case OP_VZIPL:
8359 case OP_VZIPR:
8360 return DAG.getNode(ARMISD::VZIP, dl, DAG.getVTList(VT, VT),
8361 OpLHS, OpRHS).getValue(OpNum-OP_VZIPL);
8362 case OP_VTRNL:
8363 case OP_VTRNR:
8364 return DAG.getNode(ARMISD::VTRN, dl, DAG.getVTList(VT, VT),
8365 OpLHS, OpRHS).getValue(OpNum-OP_VTRNL);
8366 }
8367}
8368
8370 ArrayRef<int> ShuffleMask,
8371 SelectionDAG &DAG) {
8372 // Check to see if we can use the VTBL instruction.
8373 SDValue V1 = Op.getOperand(0);
8374 SDValue V2 = Op.getOperand(1);
8375 SDLoc DL(Op);
8376
8377 SmallVector<SDValue, 8> VTBLMask;
8378 for (int I : ShuffleMask)
8379 VTBLMask.push_back(DAG.getSignedConstant(I, DL, MVT::i32));
8380
8381 if (V2.getNode()->isUndef())
8382 return DAG.getNode(ARMISD::VTBL1, DL, MVT::v8i8, V1,
8383 DAG.getBuildVector(MVT::v8i8, DL, VTBLMask));
8384
8385 return DAG.getNode(ARMISD::VTBL2, DL, MVT::v8i8, V1, V2,
8386 DAG.getBuildVector(MVT::v8i8, DL, VTBLMask));
8387}
8388
8390 SDLoc DL(Op);
8391 EVT VT = Op.getValueType();
8392
8393 assert((VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v16i8) &&
8394 "Expect an v8i16/v16i8 type");
8395 SDValue OpLHS = DAG.getNode(ARMISD::VREV64, DL, VT, Op.getOperand(0));
8396 // For a v16i8 type: After the VREV, we have got <7, ..., 0, 15, ..., 8>. Now,
8397 // extract the first 8 bytes into the top double word and the last 8 bytes
8398 // into the bottom double word, through a new vector shuffle that will be
8399 // turned into a VEXT on Neon, or a couple of VMOVDs on MVE.
8400 std::vector<int> NewMask;
8401 for (unsigned i = 0; i < VT.getVectorNumElements() / 2; i++)
8402 NewMask.push_back(VT.getVectorNumElements() / 2 + i);
8403 for (unsigned i = 0; i < VT.getVectorNumElements() / 2; i++)
8404 NewMask.push_back(i);
8405 return DAG.getVectorShuffle(VT, DL, OpLHS, OpLHS, NewMask);
8406}
8407
8409 switch (VT.getSimpleVT().SimpleTy) {
8410 case MVT::v2i1:
8411 return MVT::v2f64;
8412 case MVT::v4i1:
8413 return MVT::v4i32;
8414 case MVT::v8i1:
8415 return MVT::v8i16;
8416 case MVT::v16i1:
8417 return MVT::v16i8;
8418 default:
8419 llvm_unreachable("Unexpected vector predicate type");
8420 }
8421}
8422
8424 SelectionDAG &DAG) {
8425 // Converting from boolean predicates to integers involves creating a vector
8426 // of all ones or all zeroes and selecting the lanes based upon the real
8427 // predicate.
8429 DAG.getTargetConstant(ARM_AM::createVMOVModImm(0xe, 0xff), dl, MVT::i32);
8430 AllOnes = DAG.getNode(ARMISD::VMOVIMM, dl, MVT::v16i8, AllOnes);
8431
8432 SDValue AllZeroes =
8433 DAG.getTargetConstant(ARM_AM::createVMOVModImm(0xe, 0x0), dl, MVT::i32);
8434 AllZeroes = DAG.getNode(ARMISD::VMOVIMM, dl, MVT::v16i8, AllZeroes);
8435
8436 // Get full vector type from predicate type
8438
8439 SDValue RecastV1;
8440 // If the real predicate is an v8i1 or v4i1 (not v16i1) then we need to recast
8441 // this to a v16i1. This cannot be done with an ordinary bitcast because the
8442 // sizes are not the same. We have to use a MVE specific PREDICATE_CAST node,
8443 // since we know in hardware the sizes are really the same.
8444 if (VT != MVT::v16i1)
8445 RecastV1 = DAG.getNode(ARMISD::PREDICATE_CAST, dl, MVT::v16i1, Pred);
8446 else
8447 RecastV1 = Pred;
8448
8449 // Select either all ones or zeroes depending upon the real predicate bits.
8450 SDValue PredAsVector =
8451 DAG.getNode(ISD::VSELECT, dl, MVT::v16i8, RecastV1, AllOnes, AllZeroes);
8452
8453 // Recast our new predicate-as-integer v16i8 vector into something
8454 // appropriate for the shuffle, i.e. v4i32 for a real v4i1 predicate.
8455 return DAG.getNode(ISD::BITCAST, dl, NewVT, PredAsVector);
8456}
8457
8459 const ARMSubtarget *ST) {
8460 EVT VT = Op.getValueType();
8462 ArrayRef<int> ShuffleMask = SVN->getMask();
8463
8464 assert(ST->hasMVEIntegerOps() &&
8465 "No support for vector shuffle of boolean predicates");
8466
8467 SDValue V1 = Op.getOperand(0);
8468 SDValue V2 = Op.getOperand(1);
8469 SDLoc dl(Op);
8470 if (isReverseMask(ShuffleMask, VT)) {
8471 SDValue cast = DAG.getNode(ARMISD::PREDICATE_CAST, dl, MVT::i32, V1);
8472 SDValue rbit = DAG.getNode(ISD::BITREVERSE, dl, MVT::i32, cast);
8473 SDValue srl = DAG.getNode(ISD::SRL, dl, MVT::i32, rbit,
8474 DAG.getConstant(16, dl, MVT::i32));
8475 return DAG.getNode(ARMISD::PREDICATE_CAST, dl, VT, srl);
8476 }
8477
8478 // Until we can come up with optimised cases for every single vector
8479 // shuffle in existence we have chosen the least painful strategy. This is
8480 // to essentially promote the boolean predicate to a 8-bit integer, where
8481 // each predicate represents a byte. Then we fall back on a normal integer
8482 // vector shuffle and convert the result back into a predicate vector. In
8483 // many cases the generated code might be even better than scalar code
8484 // operating on bits. Just imagine trying to shuffle 8 arbitrary 2-bit
8485 // fields in a register into 8 other arbitrary 2-bit fields!
8486 SDValue PredAsVector1 = PromoteMVEPredVector(dl, V1, VT, DAG);
8487 EVT NewVT = PredAsVector1.getValueType();
8488 SDValue PredAsVector2 = V2.isUndef() ? DAG.getUNDEF(NewVT)
8489 : PromoteMVEPredVector(dl, V2, VT, DAG);
8490 assert(PredAsVector2.getValueType() == NewVT &&
8491 "Expected identical vector type in expanded i1 shuffle!");
8492
8493 // Do the shuffle!
8494 SDValue Shuffled = DAG.getVectorShuffle(NewVT, dl, PredAsVector1,
8495 PredAsVector2, ShuffleMask);
8496
8497 // Now return the result of comparing the shuffled vector with zero,
8498 // which will generate a real predicate, i.e. v4i1, v8i1 or v16i1. For a v2i1
8499 // we convert to a v4i1 compare to fill in the two halves of the i64 as i32s.
8500 if (VT == MVT::v2i1) {
8501 SDValue BC = DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, MVT::v4i32, Shuffled);
8502 SDValue Cmp = DAG.getNode(ARMISD::VCMPZ, dl, MVT::v4i1, BC,
8503 DAG.getConstant(ARMCC::NE, dl, MVT::i32));
8504 return DAG.getNode(ARMISD::PREDICATE_CAST, dl, MVT::v2i1, Cmp);
8505 }
8506 return DAG.getNode(ARMISD::VCMPZ, dl, VT, Shuffled,
8507 DAG.getConstant(ARMCC::NE, dl, MVT::i32));
8508}
8509
8511 ArrayRef<int> ShuffleMask,
8512 SelectionDAG &DAG) {
8513 // Attempt to lower the vector shuffle using as many whole register movs as
8514 // possible. This is useful for types smaller than 32bits, which would
8515 // often otherwise become a series for grp movs.
8516 SDLoc dl(Op);
8517 EVT VT = Op.getValueType();
8518 if (VT.getScalarSizeInBits() >= 32)
8519 return SDValue();
8520
8521 assert((VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v16i8) &&
8522 "Unexpected vector type");
8523 int NumElts = VT.getVectorNumElements();
8524 int QuarterSize = NumElts / 4;
8525 // The four final parts of the vector, as i32's
8526 SDValue Parts[4];
8527
8528 // Look for full lane vmovs like <0,1,2,3> or <u,5,6,7> etc, (but not
8529 // <u,u,u,u>), returning the vmov lane index
8530 auto getMovIdx = [](ArrayRef<int> ShuffleMask, int Start, int Length) {
8531 // Detect which mov lane this would be from the first non-undef element.
8532 int MovIdx = -1;
8533 for (int i = 0; i < Length; i++) {
8534 if (ShuffleMask[Start + i] >= 0) {
8535 if (ShuffleMask[Start + i] % Length != i)
8536 return -1;
8537 MovIdx = ShuffleMask[Start + i] / Length;
8538 break;
8539 }
8540 }
8541 // If all items are undef, leave this for other combines
8542 if (MovIdx == -1)
8543 return -1;
8544 // Check the remaining values are the correct part of the same mov
8545 for (int i = 1; i < Length; i++) {
8546 if (ShuffleMask[Start + i] >= 0 &&
8547 (ShuffleMask[Start + i] / Length != MovIdx ||
8548 ShuffleMask[Start + i] % Length != i))
8549 return -1;
8550 }
8551 return MovIdx;
8552 };
8553
8554 for (int Part = 0; Part < 4; ++Part) {
8555 // Does this part look like a mov
8556 int Elt = getMovIdx(ShuffleMask, Part * QuarterSize, QuarterSize);
8557 if (Elt != -1) {
8558 SDValue Input = Op->getOperand(0);
8559 if (Elt >= 4) {
8560 Input = Op->getOperand(1);
8561 Elt -= 4;
8562 }
8563 SDValue BitCast = DAG.getBitcast(MVT::v4f32, Input);
8564 Parts[Part] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f32, BitCast,
8565 DAG.getConstant(Elt, dl, MVT::i32));
8566 }
8567 }
8568
8569 // Nothing interesting found, just return
8570 if (!Parts[0] && !Parts[1] && !Parts[2] && !Parts[3])
8571 return SDValue();
8572
8573 // The other parts need to be built with the old shuffle vector, cast to a
8574 // v4i32 and extract_vector_elts
8575 if (!Parts[0] || !Parts[1] || !Parts[2] || !Parts[3]) {
8576 SmallVector<int, 16> NewShuffleMask;
8577 for (int Part = 0; Part < 4; ++Part)
8578 for (int i = 0; i < QuarterSize; i++)
8579 NewShuffleMask.push_back(
8580 Parts[Part] ? -1 : ShuffleMask[Part * QuarterSize + i]);
8581 SDValue NewShuffle = DAG.getVectorShuffle(
8582 VT, dl, Op->getOperand(0), Op->getOperand(1), NewShuffleMask);
8583 SDValue BitCast = DAG.getBitcast(MVT::v4f32, NewShuffle);
8584
8585 for (int Part = 0; Part < 4; ++Part)
8586 if (!Parts[Part])
8587 Parts[Part] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f32,
8588 BitCast, DAG.getConstant(Part, dl, MVT::i32));
8589 }
8590 // Build a vector out of the various parts and bitcast it back to the original
8591 // type.
8592 SDValue NewVec = DAG.getNode(ARMISD::BUILD_VECTOR, dl, MVT::v4f32, Parts);
8593 return DAG.getBitcast(VT, NewVec);
8594}
8595
8597 ArrayRef<int> ShuffleMask,
8598 SelectionDAG &DAG) {
8599 SDValue V1 = Op.getOperand(0);
8600 SDValue V2 = Op.getOperand(1);
8601 EVT VT = Op.getValueType();
8602 unsigned NumElts = VT.getVectorNumElements();
8603
8604 // An One-Off Identity mask is one that is mostly an identity mask from as
8605 // single source but contains a single element out-of-place, either from a
8606 // different vector or from another position in the same vector. As opposed to
8607 // lowering this via a ARMISD::BUILD_VECTOR we can generate an extract/insert
8608 // pair directly.
8609 auto isOneOffIdentityMask = [](ArrayRef<int> Mask, EVT VT, int BaseOffset,
8610 int &OffElement) {
8611 OffElement = -1;
8612 int NonUndef = 0;
8613 for (int i = 0, NumMaskElts = Mask.size(); i < NumMaskElts; ++i) {
8614 if (Mask[i] == -1)
8615 continue;
8616 NonUndef++;
8617 if (Mask[i] != i + BaseOffset) {
8618 if (OffElement == -1)
8619 OffElement = i;
8620 else
8621 return false;
8622 }
8623 }
8624 return NonUndef > 2 && OffElement != -1;
8625 };
8626 int OffElement;
8627 SDValue VInput;
8628 if (isOneOffIdentityMask(ShuffleMask, VT, 0, OffElement))
8629 VInput = V1;
8630 else if (isOneOffIdentityMask(ShuffleMask, VT, NumElts, OffElement))
8631 VInput = V2;
8632 else
8633 return SDValue();
8634
8635 SDLoc dl(Op);
8636 EVT SVT = VT.getScalarType() == MVT::i8 || VT.getScalarType() == MVT::i16
8637 ? MVT::i32
8638 : VT.getScalarType();
8639 SDValue Elt = DAG.getNode(
8640 ISD::EXTRACT_VECTOR_ELT, dl, SVT,
8641 ShuffleMask[OffElement] < (int)NumElts ? V1 : V2,
8642 DAG.getVectorIdxConstant(ShuffleMask[OffElement] % NumElts, dl));
8643 return DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, VT, VInput, Elt,
8644 DAG.getVectorIdxConstant(OffElement % NumElts, dl));
8645}
8646
8648 const ARMSubtarget *ST) {
8649 SDValue V1 = Op.getOperand(0);
8650 SDValue V2 = Op.getOperand(1);
8651 SDLoc dl(Op);
8652 EVT VT = Op.getValueType();
8654 unsigned EltSize = VT.getScalarSizeInBits();
8655
8656 if (ST->hasMVEIntegerOps() && EltSize == 1)
8657 return LowerVECTOR_SHUFFLE_i1(Op, DAG, ST);
8658
8659 // Convert shuffles that are directly supported on NEON to target-specific
8660 // DAG nodes, instead of keeping them as shuffles and matching them again
8661 // during code selection. This is more efficient and avoids the possibility
8662 // of inconsistencies between legalization and selection.
8663 // FIXME: floating-point vectors should be canonicalized to integer vectors
8664 // of the same time so that they get CSEd properly.
8665 ArrayRef<int> ShuffleMask = SVN->getMask();
8666
8667 if (EltSize <= 32) {
8668 if (SVN->isSplat()) {
8669 int Lane = SVN->getSplatIndex();
8670 // If this is undef splat, generate it via "just" vdup, if possible.
8671 if (Lane == -1) Lane = 0;
8672
8673 // Test if V1 is a SCALAR_TO_VECTOR.
8674 if (Lane == 0 && V1.getOpcode() == ISD::SCALAR_TO_VECTOR) {
8675 return DAG.getNode(ARMISD::VDUP, dl, VT, V1.getOperand(0));
8676 }
8677 // Test if V1 is a BUILD_VECTOR which is equivalent to a SCALAR_TO_VECTOR
8678 // (and probably will turn into a SCALAR_TO_VECTOR once legalization
8679 // reaches it).
8680 if (Lane == 0 && V1.getOpcode() == ISD::BUILD_VECTOR &&
8681 !isa<ConstantSDNode>(V1.getOperand(0))) {
8682 bool IsScalarToVector = true;
8683 for (unsigned i = 1, e = V1.getNumOperands(); i != e; ++i)
8684 if (!V1.getOperand(i).isUndef()) {
8685 IsScalarToVector = false;
8686 break;
8687 }
8688 if (IsScalarToVector)
8689 return DAG.getNode(ARMISD::VDUP, dl, VT, V1.getOperand(0));
8690 }
8691 return DAG.getNode(ARMISD::VDUPLANE, dl, VT, V1,
8692 DAG.getConstant(Lane, dl, MVT::i32));
8693 }
8694
8695 bool ReverseVEXT = false;
8696 unsigned Imm = 0;
8697 if (ST->hasNEON() && isVEXTMask(ShuffleMask, VT, ReverseVEXT, Imm)) {
8698 if (ReverseVEXT)
8699 std::swap(V1, V2);
8700 return DAG.getNode(ARMISD::VEXT, dl, VT, V1, V2,
8701 DAG.getConstant(Imm, dl, MVT::i32));
8702 }
8703
8704 if (isVREVMask(ShuffleMask, VT, 64))
8705 return DAG.getNode(ARMISD::VREV64, dl, VT, V1);
8706 if (isVREVMask(ShuffleMask, VT, 32))
8707 return DAG.getNode(ARMISD::VREV32, dl, VT, V1);
8708 if (isVREVMask(ShuffleMask, VT, 16))
8709 return DAG.getNode(ARMISD::VREV16, dl, VT, V1);
8710
8711 if (ST->hasNEON() && V2->isUndef() && isSingletonVEXTMask(ShuffleMask, VT, Imm)) {
8712 return DAG.getNode(ARMISD::VEXT, dl, VT, V1, V1,
8713 DAG.getConstant(Imm, dl, MVT::i32));
8714 }
8715
8716 // Check for Neon shuffles that modify both input vectors in place.
8717 // If both results are used, i.e., if there are two shuffles with the same
8718 // source operands and with masks corresponding to both results of one of
8719 // these operations, DAG memoization will ensure that a single node is
8720 // used for both shuffles.
8721 unsigned WhichResult = 0;
8722 bool isV_UNDEF = false;
8723 if (ST->hasNEON()) {
8724 if (unsigned ShuffleOpc = isNEONTwoResultShuffleMask(
8725 ShuffleMask, VT, WhichResult, isV_UNDEF)) {
8726 if (isV_UNDEF)
8727 V2 = V1;
8728 return DAG.getNode(ShuffleOpc, dl, DAG.getVTList(VT, VT), V1, V2)
8729 .getValue(WhichResult);
8730 }
8731 }
8732 if (ST->hasMVEIntegerOps()) {
8733 if (isVMOVNMask(ShuffleMask, VT, false, false))
8734 return DAG.getNode(ARMISD::VMOVN, dl, VT, V2, V1,
8735 DAG.getConstant(0, dl, MVT::i32));
8736 if (isVMOVNMask(ShuffleMask, VT, true, false))
8737 return DAG.getNode(ARMISD::VMOVN, dl, VT, V1, V2,
8738 DAG.getConstant(1, dl, MVT::i32));
8739 if (isVMOVNMask(ShuffleMask, VT, true, true))
8740 return DAG.getNode(ARMISD::VMOVN, dl, VT, V1, V1,
8741 DAG.getConstant(1, dl, MVT::i32));
8742 }
8743
8744 // Also check for these shuffles through CONCAT_VECTORS: we canonicalize
8745 // shuffles that produce a result larger than their operands with:
8746 // shuffle(concat(v1, undef), concat(v2, undef))
8747 // ->
8748 // shuffle(concat(v1, v2), undef)
8749 // because we can access quad vectors (see PerformVECTOR_SHUFFLECombine).
8750 //
8751 // This is useful in the general case, but there are special cases where
8752 // native shuffles produce larger results: the two-result ops.
8753 //
8754 // Look through the concat when lowering them:
8755 // shuffle(concat(v1, v2), undef)
8756 // ->
8757 // concat(VZIP(v1, v2):0, :1)
8758 //
8759 if (ST->hasNEON() && V1->getOpcode() == ISD::CONCAT_VECTORS && V2->isUndef()) {
8760 SDValue SubV1 = V1->getOperand(0);
8761 SDValue SubV2 = V1->getOperand(1);
8762 EVT SubVT = SubV1.getValueType();
8763
8764 // We expect these to have been canonicalized to -1.
8765 assert(llvm::all_of(ShuffleMask, [&](int i) {
8766 return i < (int)VT.getVectorNumElements();
8767 }) && "Unexpected shuffle index into UNDEF operand!");
8768
8769 if (unsigned ShuffleOpc = isNEONTwoResultShuffleMask(
8770 ShuffleMask, SubVT, WhichResult, isV_UNDEF)) {
8771 if (isV_UNDEF)
8772 SubV2 = SubV1;
8773 assert((WhichResult == 0) &&
8774 "In-place shuffle of concat can only have one result!");
8775 SDValue Res = DAG.getNode(ShuffleOpc, dl, DAG.getVTList(SubVT, SubVT),
8776 SubV1, SubV2);
8777 return DAG.getNode(ISD::CONCAT_VECTORS, dl, VT, Res.getValue(0),
8778 Res.getValue(1));
8779 }
8780 }
8781 }
8782
8783 if (ST->hasMVEIntegerOps() && EltSize <= 32 &&
8784 (ST->hasFullFP16() || VT != MVT::v8f16)) {
8785 if (SDValue V = LowerVECTOR_SHUFFLEUsingOneOff(Op, ShuffleMask, DAG))
8786 return V;
8787
8788 for (bool Top : {false, true}) {
8789 for (bool SingleSource : {false, true}) {
8790 if (isTruncMask(ShuffleMask, VT, Top, SingleSource)) {
8791 MVT FromSVT = MVT::getIntegerVT(EltSize * 2);
8792 MVT FromVT = MVT::getVectorVT(FromSVT, ShuffleMask.size() / 2);
8793 SDValue Lo = DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, FromVT, V1);
8794 SDValue Hi = DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, FromVT,
8795 SingleSource ? V1 : V2);
8796 if (Top) {
8797 SDValue Amt = DAG.getConstant(EltSize, dl, FromVT);
8798 Lo = DAG.getNode(ISD::SRL, dl, FromVT, Lo, Amt);
8799 Hi = DAG.getNode(ISD::SRL, dl, FromVT, Hi, Amt);
8800 }
8801 return DAG.getNode(ARMISD::MVETRUNC, dl, VT, Lo, Hi);
8802 }
8803 }
8804 }
8805 }
8806
8807 // If the shuffle is not directly supported and it has 4 elements, use
8808 // the PerfectShuffle-generated table to synthesize it from other shuffles.
8809 unsigned NumElts = VT.getVectorNumElements();
8810 if (NumElts == 4) {
8811 unsigned PFIndexes[4];
8812 for (unsigned i = 0; i != 4; ++i) {
8813 if (ShuffleMask[i] < 0)
8814 PFIndexes[i] = 8;
8815 else
8816 PFIndexes[i] = ShuffleMask[i];
8817 }
8818
8819 // Compute the index in the perfect shuffle table.
8820 unsigned PFTableIndex =
8821 PFIndexes[0]*9*9*9+PFIndexes[1]*9*9+PFIndexes[2]*9+PFIndexes[3];
8822 unsigned PFEntry = PerfectShuffleTable[PFTableIndex];
8823 unsigned Cost = (PFEntry >> 30);
8824
8825 if (Cost <= 4) {
8826 if (ST->hasNEON())
8827 return GeneratePerfectShuffle(PFEntry, V1, V2, DAG, dl);
8828 else if (isLegalMVEShuffleOp(PFEntry)) {
8829 unsigned LHSID = (PFEntry >> 13) & ((1 << 13)-1);
8830 unsigned RHSID = (PFEntry >> 0) & ((1 << 13)-1);
8831 unsigned PFEntryLHS = PerfectShuffleTable[LHSID];
8832 unsigned PFEntryRHS = PerfectShuffleTable[RHSID];
8833 if (isLegalMVEShuffleOp(PFEntryLHS) && isLegalMVEShuffleOp(PFEntryRHS))
8834 return GeneratePerfectShuffle(PFEntry, V1, V2, DAG, dl);
8835 }
8836 }
8837 }
8838
8839 // Implement shuffles with 32- or 64-bit elements as ARMISD::BUILD_VECTORs.
8840 if (EltSize >= 32) {
8841 // Do the expansion with floating-point types, since that is what the VFP
8842 // registers are defined to use, and since i64 is not legal.
8843 EVT EltVT = EVT::getFloatingPointVT(EltSize);
8844 EVT VecVT = EVT::getVectorVT(*DAG.getContext(), EltVT, NumElts);
8845 V1 = DAG.getNode(ISD::BITCAST, dl, VecVT, V1);
8846 V2 = DAG.getNode(ISD::BITCAST, dl, VecVT, V2);
8848 for (unsigned i = 0; i < NumElts; ++i) {
8849 if (ShuffleMask[i] < 0)
8850 Ops.push_back(DAG.getUNDEF(EltVT));
8851 else
8852 Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT,
8853 ShuffleMask[i] < (int)NumElts ? V1 : V2,
8854 DAG.getConstant(ShuffleMask[i] & (NumElts-1),
8855 dl, MVT::i32)));
8856 }
8857 SDValue Val = DAG.getNode(ARMISD::BUILD_VECTOR, dl, VecVT, Ops);
8858 return DAG.getNode(ISD::BITCAST, dl, VT, Val);
8859 }
8860
8861 if ((VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v16i8) &&
8862 isReverseMask(ShuffleMask, VT))
8863 return LowerReverse_VECTOR_SHUFFLE(Op, DAG);
8864
8865 if (ST->hasNEON() && VT == MVT::v8i8)
8866 if (SDValue NewOp = LowerVECTOR_SHUFFLEv8i8(Op, ShuffleMask, DAG))
8867 return NewOp;
8868
8869 if (ST->hasMVEIntegerOps())
8870 if (SDValue NewOp = LowerVECTOR_SHUFFLEUsingMovs(Op, ShuffleMask, DAG))
8871 return NewOp;
8872
8873 // Lower v8f16 via v8i16 to avoid invalid f16 nodes.
8874 if (VT == MVT::v8f16 && !ST->hasFullFP16()) {
8875 SDValue BC0 =
8876 DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, MVT::v8i16, Op.getOperand(0));
8877 SDValue BC1 =
8878 DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, MVT::v8i16, Op.getOperand(1));
8879 SDValue Shuf = DAG.getVectorShuffle(MVT::v8i16, dl, BC0, BC1, ShuffleMask);
8880 return DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, VT, Shuf);
8881 }
8882
8883 return SDValue();
8884}
8885
8887 const ARMSubtarget *ST) {
8888 EVT VecVT = Op.getOperand(0).getValueType();
8889 SDLoc dl(Op);
8890
8891 assert(ST->hasMVEIntegerOps() &&
8892 "LowerINSERT_VECTOR_ELT_i1 called without MVE!");
8893
8894 SDValue Conv =
8895 DAG.getNode(ARMISD::PREDICATE_CAST, dl, MVT::i32, Op->getOperand(0));
8896 unsigned Lane = Op.getConstantOperandVal(2);
8897 unsigned LaneWidth =
8899 unsigned Mask = ((1 << LaneWidth) - 1) << Lane * LaneWidth;
8900 SDValue Ext = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, MVT::i32,
8901 Op.getOperand(1), DAG.getValueType(MVT::i1));
8902 SDValue BFI = DAG.getNode(ARMISD::BFI, dl, MVT::i32, Conv, Ext,
8903 DAG.getConstant(~Mask, dl, MVT::i32));
8904 return DAG.getNode(ARMISD::PREDICATE_CAST, dl, Op.getValueType(), BFI);
8905}
8906
8907SDValue ARMTargetLowering::LowerINSERT_VECTOR_ELT(SDValue Op,
8908 SelectionDAG &DAG) const {
8909 // INSERT_VECTOR_ELT is legal only for immediate indexes.
8910 SDValue Lane = Op.getOperand(2);
8911 if (!isa<ConstantSDNode>(Lane))
8912 return SDValue();
8913
8914 SDValue Elt = Op.getOperand(1);
8915 EVT EltVT = Elt.getValueType();
8916
8917 if (Subtarget->hasMVEIntegerOps() &&
8918 Op.getValueType().getScalarSizeInBits() == 1)
8919 return LowerINSERT_VECTOR_ELT_i1(Op, DAG, Subtarget);
8920
8921 if (getTypeAction(*DAG.getContext(), EltVT) ==
8923 // INSERT_VECTOR_ELT doesn't want f16 operands promoting to f32,
8924 // but the type system will try to do that if we don't intervene.
8925 // Reinterpret any such vector-element insertion as one with the
8926 // corresponding integer types.
8927
8928 SDLoc dl(Op);
8929
8930 EVT IEltVT = MVT::getIntegerVT(EltVT.getScalarSizeInBits());
8931 assert(getTypeAction(*DAG.getContext(), IEltVT) !=
8933
8934 SDValue VecIn = Op.getOperand(0);
8935 EVT VecVT = VecIn.getValueType();
8936 EVT IVecVT = EVT::getVectorVT(*DAG.getContext(), IEltVT,
8937 VecVT.getVectorNumElements());
8938
8939 SDValue IElt = DAG.getNode(ISD::BITCAST, dl, IEltVT, Elt);
8940 SDValue IVecIn = DAG.getNode(ISD::BITCAST, dl, IVecVT, VecIn);
8941 SDValue IVecOut = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, IVecVT,
8942 IVecIn, IElt, Lane);
8943 return DAG.getNode(ISD::BITCAST, dl, VecVT, IVecOut);
8944 }
8945
8946 return Op;
8947}
8948
8950 const ARMSubtarget *ST) {
8951 EVT VecVT = Op.getOperand(0).getValueType();
8952 SDLoc dl(Op);
8953
8954 assert(ST->hasMVEIntegerOps() &&
8955 "LowerINSERT_VECTOR_ELT_i1 called without MVE!");
8956
8957 SDValue Conv =
8958 DAG.getNode(ARMISD::PREDICATE_CAST, dl, MVT::i32, Op->getOperand(0));
8959 unsigned Lane = Op.getConstantOperandVal(1);
8960 unsigned LaneWidth =
8962 SDValue Shift = DAG.getNode(ISD::SRL, dl, MVT::i32, Conv,
8963 DAG.getConstant(Lane * LaneWidth, dl, MVT::i32));
8964 return Shift;
8965}
8966
8968 const ARMSubtarget *ST) {
8969 // EXTRACT_VECTOR_ELT is legal only for immediate indexes.
8970 SDValue Lane = Op.getOperand(1);
8971 if (!isa<ConstantSDNode>(Lane))
8972 return SDValue();
8973
8974 SDValue Vec = Op.getOperand(0);
8975 EVT VT = Vec.getValueType();
8976
8977 if (ST->hasMVEIntegerOps() && VT.getScalarSizeInBits() == 1)
8978 return LowerEXTRACT_VECTOR_ELT_i1(Op, DAG, ST);
8979
8980 if (Op.getValueType() == MVT::i32 && Vec.getScalarValueSizeInBits() < 32) {
8981 SDLoc dl(Op);
8982 return DAG.getNode(ARMISD::VGETLANEu, dl, MVT::i32, Vec, Lane);
8983 }
8984
8985 return Op;
8986}
8987
8989 const ARMSubtarget *ST) {
8990 SDLoc dl(Op);
8991 assert(Op.getValueType().getScalarSizeInBits() == 1 &&
8992 "Unexpected custom CONCAT_VECTORS lowering");
8993 assert(isPowerOf2_32(Op.getNumOperands()) &&
8994 "Unexpected custom CONCAT_VECTORS lowering");
8995 assert(ST->hasMVEIntegerOps() &&
8996 "CONCAT_VECTORS lowering only supported for MVE");
8997
8998 auto ConcatPair = [&](SDValue V1, SDValue V2) {
8999 EVT Op1VT = V1.getValueType();
9000 EVT Op2VT = V2.getValueType();
9001 assert(Op1VT == Op2VT && "Operand types don't match!");
9002 assert((Op1VT == MVT::v2i1 || Op1VT == MVT::v4i1 || Op1VT == MVT::v8i1) &&
9003 "Unexpected i1 concat operations!");
9004 EVT VT = Op1VT.getDoubleNumVectorElementsVT(*DAG.getContext());
9005
9006 SDValue NewV1 = PromoteMVEPredVector(dl, V1, Op1VT, DAG);
9007 SDValue NewV2 = PromoteMVEPredVector(dl, V2, Op2VT, DAG);
9008
9009 // We now have Op1 + Op2 promoted to vectors of integers, where v8i1 gets
9010 // promoted to v8i16, etc.
9011 MVT ElType =
9013 unsigned NumElts = 2 * Op1VT.getVectorNumElements();
9014
9015 EVT ConcatVT = MVT::getVectorVT(ElType, NumElts);
9016 if (Op1VT == MVT::v4i1 || Op1VT == MVT::v8i1) {
9017 // Use MVETRUNC to truncate the combined NewV1::NewV2 into the smaller
9018 // ConcatVT.
9019 SDValue ConVec =
9020 DAG.getNode(ARMISD::MVETRUNC, dl, ConcatVT, NewV1, NewV2);
9021 return DAG.getNode(ARMISD::VCMPZ, dl, VT, ConVec,
9022 DAG.getConstant(ARMCC::NE, dl, MVT::i32));
9023 }
9024
9025 // Extract the vector elements from Op1 and Op2 one by one and truncate them
9026 // to be the right size for the destination. For example, if Op1 is v4i1
9027 // then the promoted vector is v4i32. The result of concatenation gives a
9028 // v8i1, which when promoted is v8i16. That means each i32 element from Op1
9029 // needs truncating to i16 and inserting in the result.
9030 auto ExtractInto = [&DAG, &dl](SDValue NewV, SDValue ConVec, unsigned &j) {
9031 EVT NewVT = NewV.getValueType();
9032 EVT ConcatVT = ConVec.getValueType();
9033 unsigned ExtScale = 1;
9034 if (NewVT == MVT::v2f64) {
9035 NewV = DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, MVT::v4i32, NewV);
9036 ExtScale = 2;
9037 }
9038 for (unsigned i = 0, e = NewVT.getVectorNumElements(); i < e; i++, j++) {
9039 SDValue Elt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i32, NewV,
9040 DAG.getIntPtrConstant(i * ExtScale, dl));
9041 ConVec = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, ConcatVT, ConVec, Elt,
9042 DAG.getConstant(j, dl, MVT::i32));
9043 }
9044 return ConVec;
9045 };
9046 unsigned j = 0;
9047 SDValue ConVec = DAG.getNode(ISD::UNDEF, dl, ConcatVT);
9048 ConVec = ExtractInto(NewV1, ConVec, j);
9049 ConVec = ExtractInto(NewV2, ConVec, j);
9050
9051 // Now return the result of comparing the subvector with zero, which will
9052 // generate a real predicate, i.e. v4i1, v8i1 or v16i1.
9053 return DAG.getNode(ARMISD::VCMPZ, dl, VT, ConVec,
9054 DAG.getConstant(ARMCC::NE, dl, MVT::i32));
9055 };
9056
9057 // Concat each pair of subvectors and pack into the lower half of the array.
9058 SmallVector<SDValue> ConcatOps(Op->ops());
9059 while (ConcatOps.size() > 1) {
9060 for (unsigned I = 0, E = ConcatOps.size(); I != E; I += 2) {
9061 SDValue V1 = ConcatOps[I];
9062 SDValue V2 = ConcatOps[I + 1];
9063 ConcatOps[I / 2] = ConcatPair(V1, V2);
9064 }
9065 ConcatOps.resize(ConcatOps.size() / 2);
9066 }
9067 return ConcatOps[0];
9068}
9069
9071 const ARMSubtarget *ST) {
9072 EVT VT = Op->getValueType(0);
9073 if (ST->hasMVEIntegerOps() && VT.getScalarSizeInBits() == 1)
9074 return LowerCONCAT_VECTORS_i1(Op, DAG, ST);
9075
9076 // The only time a CONCAT_VECTORS operation can have legal types is when
9077 // two 64-bit vectors are concatenated to a 128-bit vector.
9078 assert(Op.getValueType().is128BitVector() && Op.getNumOperands() == 2 &&
9079 "unexpected CONCAT_VECTORS");
9080 SDLoc dl(Op);
9081 SDValue Val = DAG.getUNDEF(MVT::v2f64);
9082 SDValue Op0 = Op.getOperand(0);
9083 SDValue Op1 = Op.getOperand(1);
9084 if (!Op0.isUndef())
9085 Val = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, MVT::v2f64, Val,
9086 DAG.getNode(ISD::BITCAST, dl, MVT::f64, Op0),
9087 DAG.getIntPtrConstant(0, dl));
9088 if (!Op1.isUndef())
9089 Val = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, MVT::v2f64, Val,
9090 DAG.getNode(ISD::BITCAST, dl, MVT::f64, Op1),
9091 DAG.getIntPtrConstant(1, dl));
9092 return DAG.getNode(ISD::BITCAST, dl, Op.getValueType(), Val);
9093}
9094
9096 const ARMSubtarget *ST) {
9097 SDValue V1 = Op.getOperand(0);
9098 SDValue V2 = Op.getOperand(1);
9099 SDLoc dl(Op);
9100 EVT VT = Op.getValueType();
9101 EVT Op1VT = V1.getValueType();
9102 unsigned NumElts = VT.getVectorNumElements();
9103 unsigned Index = V2->getAsZExtVal();
9104
9105 assert(VT.getScalarSizeInBits() == 1 &&
9106 "Unexpected custom EXTRACT_SUBVECTOR lowering");
9107 assert(ST->hasMVEIntegerOps() &&
9108 "EXTRACT_SUBVECTOR lowering only supported for MVE");
9109
9110 SDValue NewV1 = PromoteMVEPredVector(dl, V1, Op1VT, DAG);
9111
9112 // We now have Op1 promoted to a vector of integers, where v8i1 gets
9113 // promoted to v8i16, etc.
9114
9116
9117 if (NumElts == 2) {
9118 EVT SubVT = MVT::v4i32;
9119 SDValue SubVec = DAG.getNode(ISD::UNDEF, dl, SubVT);
9120 for (unsigned i = Index, j = 0; i < (Index + NumElts); i++, j += 2) {
9121 SDValue Elt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i32, NewV1,
9122 DAG.getIntPtrConstant(i, dl));
9123 SubVec = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, SubVT, SubVec, Elt,
9124 DAG.getConstant(j, dl, MVT::i32));
9125 SubVec = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, SubVT, SubVec, Elt,
9126 DAG.getConstant(j + 1, dl, MVT::i32));
9127 }
9128 SDValue Cmp = DAG.getNode(ARMISD::VCMPZ, dl, MVT::v4i1, SubVec,
9129 DAG.getConstant(ARMCC::NE, dl, MVT::i32));
9130 return DAG.getNode(ARMISD::PREDICATE_CAST, dl, MVT::v2i1, Cmp);
9131 }
9132
9133 EVT SubVT = MVT::getVectorVT(ElType, NumElts);
9134 SDValue SubVec = DAG.getNode(ISD::UNDEF, dl, SubVT);
9135 for (unsigned i = Index, j = 0; i < (Index + NumElts); i++, j++) {
9136 SDValue Elt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i32, NewV1,
9137 DAG.getIntPtrConstant(i, dl));
9138 SubVec = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, SubVT, SubVec, Elt,
9139 DAG.getConstant(j, dl, MVT::i32));
9140 }
9141
9142 // Now return the result of comparing the subvector with zero,
9143 // which will generate a real predicate, i.e. v4i1, v8i1 or v16i1.
9144 return DAG.getNode(ARMISD::VCMPZ, dl, VT, SubVec,
9145 DAG.getConstant(ARMCC::NE, dl, MVT::i32));
9146}
9147
9148// Turn a truncate into a predicate (an i1 vector) into icmp(and(x, 1), 0).
9150 const ARMSubtarget *ST) {
9151 assert(ST->hasMVEIntegerOps() && "Expected MVE!");
9152 EVT VT = N->getValueType(0);
9153 assert((VT == MVT::v16i1 || VT == MVT::v8i1 || VT == MVT::v4i1) &&
9154 "Expected a vector i1 type!");
9155 SDValue Op = N->getOperand(0);
9156 EVT FromVT = Op.getValueType();
9157 SDLoc DL(N);
9158
9159 SDValue And =
9160 DAG.getNode(ISD::AND, DL, FromVT, Op, DAG.getConstant(1, DL, FromVT));
9161 return DAG.getNode(ISD::SETCC, DL, VT, And, DAG.getConstant(0, DL, FromVT),
9162 DAG.getCondCode(ISD::SETNE));
9163}
9164
9166 const ARMSubtarget *Subtarget) {
9167 if (!Subtarget->hasMVEIntegerOps())
9168 return SDValue();
9169
9170 EVT ToVT = N->getValueType(0);
9171 if (ToVT.getScalarType() == MVT::i1)
9172 return LowerTruncatei1(N, DAG, Subtarget);
9173
9174 // MVE does not have a single instruction to perform the truncation of a v4i32
9175 // into the lower half of a v8i16, in the same way that a NEON vmovn would.
9176 // Most of the instructions in MVE follow the 'Beats' system, where moving
9177 // values from different lanes is usually something that the instructions
9178 // avoid.
9179 //
9180 // Instead it has top/bottom instructions such as VMOVLT/B and VMOVNT/B,
9181 // which take a the top/bottom half of a larger lane and extend it (or do the
9182 // opposite, truncating into the top/bottom lane from a larger lane). Note
9183 // that because of the way we widen lanes, a v4i16 is really a v4i32 using the
9184 // bottom 16bits from each vector lane. This works really well with T/B
9185 // instructions, but that doesn't extend to v8i32->v8i16 where the lanes need
9186 // to move order.
9187 //
9188 // But truncates and sext/zext are always going to be fairly common from llvm.
9189 // We have several options for how to deal with them:
9190 // - Wherever possible combine them into an instruction that makes them
9191 // "free". This includes loads/stores, which can perform the trunc as part
9192 // of the memory operation. Or certain shuffles that can be turned into
9193 // VMOVN/VMOVL.
9194 // - Lane Interleaving to transform blocks surrounded by ext/trunc. So
9195 // trunc(mul(sext(a), sext(b))) may become
9196 // VMOVNT(VMUL(VMOVLB(a), VMOVLB(b)), VMUL(VMOVLT(a), VMOVLT(b))). (Which in
9197 // this case can use VMULL). This is performed in the
9198 // MVELaneInterleavingPass.
9199 // - Otherwise we have an option. By default we would expand the
9200 // zext/sext/trunc into a series of lane extract/inserts going via GPR
9201 // registers. One for each vector lane in the vector. This can obviously be
9202 // very expensive.
9203 // - The other option is to use the fact that loads/store can extend/truncate
9204 // to turn a trunc into two truncating stack stores and a stack reload. This
9205 // becomes 3 back-to-back memory operations, but at least that is less than
9206 // all the insert/extracts.
9207 //
9208 // In order to do the last, we convert certain trunc's into MVETRUNC, which
9209 // are either optimized where they can be, or eventually lowered into stack
9210 // stores/loads. This prevents us from splitting a v8i16 trunc into two stores
9211 // two early, where other instructions would be better, and stops us from
9212 // having to reconstruct multiple buildvector shuffles into loads/stores.
9213 if (ToVT != MVT::v8i16 && ToVT != MVT::v16i8)
9214 return SDValue();
9215 EVT FromVT = N->getOperand(0).getValueType();
9216 if (FromVT != MVT::v8i32 && FromVT != MVT::v16i16)
9217 return SDValue();
9218
9219 SDValue Lo, Hi;
9220 std::tie(Lo, Hi) = DAG.SplitVectorOperand(N, 0);
9221 SDLoc DL(N);
9222 return DAG.getNode(ARMISD::MVETRUNC, DL, ToVT, Lo, Hi);
9223}
9224
9226 const ARMSubtarget *Subtarget) {
9227 if (!Subtarget->hasMVEIntegerOps())
9228 return SDValue();
9229
9230 // See LowerTruncate above for an explanation of MVEEXT/MVETRUNC.
9231
9232 EVT ToVT = N->getValueType(0);
9233 if (ToVT != MVT::v16i32 && ToVT != MVT::v8i32 && ToVT != MVT::v16i16)
9234 return SDValue();
9235 SDValue Op = N->getOperand(0);
9236 EVT FromVT = Op.getValueType();
9237 if (FromVT != MVT::v8i16 && FromVT != MVT::v16i8)
9238 return SDValue();
9239
9240 SDLoc DL(N);
9241 EVT ExtVT = ToVT.getHalfNumVectorElementsVT(*DAG.getContext());
9242 if (ToVT.getScalarType() == MVT::i32 && FromVT.getScalarType() == MVT::i8)
9243 ExtVT = MVT::v8i16;
9244
9245 unsigned Opcode =
9247 SDValue Ext = DAG.getNode(Opcode, DL, DAG.getVTList(ExtVT, ExtVT), Op);
9248 SDValue Ext1 = Ext.getValue(1);
9249
9250 if (ToVT.getScalarType() == MVT::i32 && FromVT.getScalarType() == MVT::i8) {
9251 Ext = DAG.getNode(N->getOpcode(), DL, MVT::v8i32, Ext);
9252 Ext1 = DAG.getNode(N->getOpcode(), DL, MVT::v8i32, Ext1);
9253 }
9254
9255 return DAG.getNode(ISD::CONCAT_VECTORS, DL, ToVT, Ext, Ext1);
9256}
9257
9258/// isExtendedBUILD_VECTOR - Check if N is a constant BUILD_VECTOR where each
9259/// element has been zero/sign-extended, depending on the isSigned parameter,
9260/// from an integer type half its size.
9262 bool isSigned) {
9263 // A v2i64 BUILD_VECTOR will have been legalized to a BITCAST from v4i32.
9264 EVT VT = N->getValueType(0);
9265 if (VT == MVT::v2i64 && N->getOpcode() == ISD::BITCAST) {
9266 SDNode *BVN = N->getOperand(0).getNode();
9267 if (BVN->getValueType(0) != MVT::v4i32 ||
9268 BVN->getOpcode() != ISD::BUILD_VECTOR)
9269 return false;
9270 unsigned LoElt = DAG.getDataLayout().isBigEndian() ? 1 : 0;
9271 unsigned HiElt = 1 - LoElt;
9276 if (!Lo0 || !Hi0 || !Lo1 || !Hi1)
9277 return false;
9278 if (isSigned) {
9279 if (Hi0->getSExtValue() == Lo0->getSExtValue() >> 32 &&
9280 Hi1->getSExtValue() == Lo1->getSExtValue() >> 32)
9281 return true;
9282 } else {
9283 if (Hi0->isZero() && Hi1->isZero())
9284 return true;
9285 }
9286 return false;
9287 }
9288
9289 if (N->getOpcode() != ISD::BUILD_VECTOR)
9290 return false;
9291
9292 for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
9293 SDNode *Elt = N->getOperand(i).getNode();
9295 unsigned EltSize = VT.getScalarSizeInBits();
9296 unsigned HalfSize = EltSize / 2;
9297 if (isSigned) {
9298 if (!isIntN(HalfSize, C->getSExtValue()))
9299 return false;
9300 } else {
9301 if (!isUIntN(HalfSize, C->getZExtValue()))
9302 return false;
9303 }
9304 continue;
9305 }
9306 return false;
9307 }
9308
9309 return true;
9310}
9311
9312/// isSignExtended - Check if a node is a vector value that is sign-extended
9313/// or a constant BUILD_VECTOR with sign-extended elements.
9315 if (N->getOpcode() == ISD::SIGN_EXTEND || ISD::isSEXTLoad(N))
9316 return true;
9317 if (isExtendedBUILD_VECTOR(N, DAG, true))
9318 return true;
9319 return false;
9320}
9321
9322/// isZeroExtended - Check if a node is a vector value that is zero-extended (or
9323/// any-extended) or a constant BUILD_VECTOR with zero-extended elements.
9325 if (N->getOpcode() == ISD::ZERO_EXTEND || N->getOpcode() == ISD::ANY_EXTEND ||
9327 return true;
9328 if (isExtendedBUILD_VECTOR(N, DAG, false))
9329 return true;
9330 return false;
9331}
9332
9333static EVT getExtensionTo64Bits(const EVT &OrigVT) {
9334 if (OrigVT.getSizeInBits() >= 64)
9335 return OrigVT;
9336
9337 assert(OrigVT.isSimple() && "Expecting a simple value type");
9338
9339 MVT::SimpleValueType OrigSimpleTy = OrigVT.getSimpleVT().SimpleTy;
9340 switch (OrigSimpleTy) {
9341 default: llvm_unreachable("Unexpected Vector Type");
9342 case MVT::v2i8:
9343 case MVT::v2i16:
9344 return MVT::v2i32;
9345 case MVT::v4i8:
9346 return MVT::v4i16;
9347 }
9348}
9349
9350/// AddRequiredExtensionForVMULL - Add a sign/zero extension to extend the total
9351/// value size to 64 bits. We need a 64-bit D register as an operand to VMULL.
9352/// We insert the required extension here to get the vector to fill a D register.
9354 const EVT &OrigTy,
9355 const EVT &ExtTy,
9356 unsigned ExtOpcode) {
9357 // The vector originally had a size of OrigTy. It was then extended to ExtTy.
9358 // We expect the ExtTy to be 128-bits total. If the OrigTy is less than
9359 // 64-bits we need to insert a new extension so that it will be 64-bits.
9360 assert(ExtTy.is128BitVector() && "Unexpected extension size");
9361 if (OrigTy.getSizeInBits() >= 64)
9362 return N;
9363
9364 // Must extend size to at least 64 bits to be used as an operand for VMULL.
9365 EVT NewVT = getExtensionTo64Bits(OrigTy);
9366
9367 return DAG.getNode(ExtOpcode, SDLoc(N), NewVT, N);
9368}
9369
9370/// SkipLoadExtensionForVMULL - return a load of the original vector size that
9371/// does not do any sign/zero extension. If the original vector is less
9372/// than 64 bits, an appropriate extension will be added after the load to
9373/// reach a total size of 64 bits. We have to add the extension separately
9374/// because ARM does not have a sign/zero extending load for vectors.
9376 EVT ExtendedTy = getExtensionTo64Bits(LD->getMemoryVT());
9377
9378 // The load already has the right type.
9379 if (ExtendedTy == LD->getMemoryVT())
9380 return DAG.getLoad(LD->getMemoryVT(), SDLoc(LD), LD->getChain(),
9381 LD->getBasePtr(), LD->getPointerInfo(), LD->getAlign(),
9382 LD->getMemOperand()->getFlags());
9383
9384 // We need to create a zextload/sextload. We cannot just create a load
9385 // followed by a zext/zext node because LowerMUL is also run during normal
9386 // operation legalization where we can't create illegal types.
9387 return DAG.getExtLoad(LD->getExtensionType(), SDLoc(LD), ExtendedTy,
9388 LD->getChain(), LD->getBasePtr(), LD->getPointerInfo(),
9389 LD->getMemoryVT(), LD->getAlign(),
9390 LD->getMemOperand()->getFlags());
9391}
9392
9393/// SkipExtensionForVMULL - For a node that is a SIGN_EXTEND, ZERO_EXTEND,
9394/// ANY_EXTEND, extending load, or BUILD_VECTOR with extended elements, return
9395/// the unextended value. The unextended vector should be 64 bits so that it can
9396/// be used as an operand to a VMULL instruction. If the original vector size
9397/// before extension is less than 64 bits we add a an extension to resize
9398/// the vector to 64 bits.
9400 if (N->getOpcode() == ISD::SIGN_EXTEND ||
9401 N->getOpcode() == ISD::ZERO_EXTEND || N->getOpcode() == ISD::ANY_EXTEND)
9402 return AddRequiredExtensionForVMULL(N->getOperand(0), DAG,
9403 N->getOperand(0)->getValueType(0),
9404 N->getValueType(0),
9405 N->getOpcode());
9406
9407 if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N)) {
9408 assert((ISD::isSEXTLoad(LD) || ISD::isZEXTLoad(LD)) &&
9409 "Expected extending load");
9410
9411 SDValue newLoad = SkipLoadExtensionForVMULL(LD, DAG);
9412 DAG.ReplaceAllUsesOfValueWith(SDValue(LD, 1), newLoad.getValue(1));
9413 unsigned Opcode = ISD::isSEXTLoad(LD) ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND;
9414 SDValue extLoad =
9415 DAG.getNode(Opcode, SDLoc(newLoad), LD->getValueType(0), newLoad);
9416 DAG.ReplaceAllUsesOfValueWith(SDValue(LD, 0), extLoad);
9417
9418 return newLoad;
9419 }
9420
9421 // Otherwise, the value must be a BUILD_VECTOR. For v2i64, it will
9422 // have been legalized as a BITCAST from v4i32.
9423 if (N->getOpcode() == ISD::BITCAST) {
9424 SDNode *BVN = N->getOperand(0).getNode();
9426 BVN->getValueType(0) == MVT::v4i32 && "expected v4i32 BUILD_VECTOR");
9427 unsigned LowElt = DAG.getDataLayout().isBigEndian() ? 1 : 0;
9428 return DAG.getBuildVector(
9429 MVT::v2i32, SDLoc(N),
9430 {BVN->getOperand(LowElt), BVN->getOperand(LowElt + 2)});
9431 }
9432 // Construct a new BUILD_VECTOR with elements truncated to half the size.
9433 assert(N->getOpcode() == ISD::BUILD_VECTOR && "expected BUILD_VECTOR");
9434 EVT VT = N->getValueType(0);
9435 unsigned EltSize = VT.getScalarSizeInBits() / 2;
9436 unsigned NumElts = VT.getVectorNumElements();
9437 MVT TruncVT = MVT::getIntegerVT(EltSize);
9439 SDLoc dl(N);
9440 for (unsigned i = 0; i != NumElts; ++i) {
9441 const APInt &CInt = N->getConstantOperandAPInt(i);
9442 // Element types smaller than 32 bits are not legal, so use i32 elements.
9443 // The values are implicitly truncated so sext vs. zext doesn't matter.
9444 Ops.push_back(DAG.getConstant(CInt.zextOrTrunc(32), dl, MVT::i32));
9445 }
9446 return DAG.getBuildVector(MVT::getVectorVT(TruncVT, NumElts), dl, Ops);
9447}
9448
9449static bool isAddSubSExt(SDNode *N, SelectionDAG &DAG) {
9450 unsigned Opcode = N->getOpcode();
9451 if (Opcode == ISD::ADD || Opcode == ISD::SUB) {
9452 SDNode *N0 = N->getOperand(0).getNode();
9453 SDNode *N1 = N->getOperand(1).getNode();
9454 return N0->hasOneUse() && N1->hasOneUse() &&
9455 isSignExtended(N0, DAG) && isSignExtended(N1, DAG);
9456 }
9457 return false;
9458}
9459
9460static bool isAddSubZExt(SDNode *N, SelectionDAG &DAG) {
9461 unsigned Opcode = N->getOpcode();
9462 if (Opcode == ISD::ADD || Opcode == ISD::SUB) {
9463 SDNode *N0 = N->getOperand(0).getNode();
9464 SDNode *N1 = N->getOperand(1).getNode();
9465 return N0->hasOneUse() && N1->hasOneUse() &&
9466 isZeroExtended(N0, DAG) && isZeroExtended(N1, DAG);
9467 }
9468 return false;
9469}
9470
9472 // Multiplications are only custom-lowered for 128-bit vectors so that
9473 // VMULL can be detected. Otherwise v2i64 multiplications are not legal.
9474 EVT VT = Op.getValueType();
9475 assert(VT.is128BitVector() && VT.isInteger() &&
9476 "unexpected type for custom-lowering ISD::MUL");
9477 SDNode *N0 = Op.getOperand(0).getNode();
9478 SDNode *N1 = Op.getOperand(1).getNode();
9479 unsigned NewOpc = 0;
9480 bool isMLA = false;
9481 bool isN0SExt = isSignExtended(N0, DAG);
9482 bool isN1SExt = isSignExtended(N1, DAG);
9483 if (isN0SExt && isN1SExt)
9484 NewOpc = ARMISD::VMULLs;
9485 else {
9486 bool isN0ZExt = isZeroExtended(N0, DAG);
9487 bool isN1ZExt = isZeroExtended(N1, DAG);
9488 if (isN0ZExt && isN1ZExt)
9489 NewOpc = ARMISD::VMULLu;
9490 else if (isN1SExt || isN1ZExt) {
9491 // Look for (s/zext A + s/zext B) * (s/zext C). We want to turn these
9492 // into (s/zext A * s/zext C) + (s/zext B * s/zext C)
9493 if (isN1SExt && isAddSubSExt(N0, DAG)) {
9494 NewOpc = ARMISD::VMULLs;
9495 isMLA = true;
9496 } else if (isN1ZExt && isAddSubZExt(N0, DAG)) {
9497 NewOpc = ARMISD::VMULLu;
9498 isMLA = true;
9499 } else if (isN0ZExt && isAddSubZExt(N1, DAG)) {
9500 std::swap(N0, N1);
9501 NewOpc = ARMISD::VMULLu;
9502 isMLA = true;
9503 }
9504 }
9505
9506 if (!NewOpc) {
9507 if (VT == MVT::v2i64)
9508 // Fall through to expand this. It is not legal.
9509 return SDValue();
9510 else
9511 // Other vector multiplications are legal.
9512 return Op;
9513 }
9514 }
9515
9516 // Legalize to a VMULL instruction.
9517 SDLoc DL(Op);
9518 SDValue Op0;
9519 SDValue Op1 = SkipExtensionForVMULL(N1, DAG);
9520 if (!isMLA) {
9521 Op0 = SkipExtensionForVMULL(N0, DAG);
9523 Op1.getValueType().is64BitVector() &&
9524 "unexpected types for extended operands to VMULL");
9525 return DAG.getNode(NewOpc, DL, VT, Op0, Op1);
9526 }
9527
9528 // Optimizing (zext A + zext B) * C, to (VMULL A, C) + (VMULL B, C) during
9529 // isel lowering to take advantage of no-stall back to back vmul + vmla.
9530 // vmull q0, d4, d6
9531 // vmlal q0, d5, d6
9532 // is faster than
9533 // vaddl q0, d4, d5
9534 // vmovl q1, d6
9535 // vmul q0, q0, q1
9536 SDValue N00 = SkipExtensionForVMULL(N0->getOperand(0).getNode(), DAG);
9537 SDValue N01 = SkipExtensionForVMULL(N0->getOperand(1).getNode(), DAG);
9538 EVT Op1VT = Op1.getValueType();
9539 return DAG.getNode(N0->getOpcode(), DL, VT,
9540 DAG.getNode(NewOpc, DL, VT,
9541 DAG.getNode(ISD::BITCAST, DL, Op1VT, N00), Op1),
9542 DAG.getNode(NewOpc, DL, VT,
9543 DAG.getNode(ISD::BITCAST, DL, Op1VT, N01), Op1));
9544}
9545
9547 SelectionDAG &DAG) {
9548 // TODO: Should this propagate fast-math-flags?
9549
9550 // Convert to float
9551 // float4 xf = vcvt_f32_s32(vmovl_s16(a.lo));
9552 // float4 yf = vcvt_f32_s32(vmovl_s16(b.lo));
9553 X = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::v4i32, X);
9554 Y = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::v4i32, Y);
9555 X = DAG.getNode(ISD::SINT_TO_FP, dl, MVT::v4f32, X);
9556 Y = DAG.getNode(ISD::SINT_TO_FP, dl, MVT::v4f32, Y);
9557 // Get reciprocal estimate.
9558 // float4 recip = vrecpeq_f32(yf);
9559 Y = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, MVT::v4f32,
9560 DAG.getConstant(Intrinsic::arm_neon_vrecpe, dl, MVT::i32),
9561 Y);
9562 // Because char has a smaller range than uchar, we can actually get away
9563 // without any newton steps. This requires that we use a weird bias
9564 // of 0xb000, however (again, this has been exhaustively tested).
9565 // float4 result = as_float4(as_int4(xf*recip) + 0xb000);
9566 X = DAG.getNode(ISD::FMUL, dl, MVT::v4f32, X, Y);
9567 X = DAG.getNode(ISD::BITCAST, dl, MVT::v4i32, X);
9568 Y = DAG.getConstant(0xb000, dl, MVT::v4i32);
9569 X = DAG.getNode(ISD::ADD, dl, MVT::v4i32, X, Y);
9570 X = DAG.getNode(ISD::BITCAST, dl, MVT::v4f32, X);
9571 // Convert back to short.
9572 X = DAG.getNode(ISD::FP_TO_SINT, dl, MVT::v4i32, X);
9573 X = DAG.getNode(ISD::TRUNCATE, dl, MVT::v4i16, X);
9574 return X;
9575}
9576
9578 SelectionDAG &DAG) {
9579 // TODO: Should this propagate fast-math-flags?
9580
9581 SDValue N2;
9582 // Convert to float.
9583 // float4 yf = vcvt_f32_s32(vmovl_s16(y));
9584 // float4 xf = vcvt_f32_s32(vmovl_s16(x));
9585 N0 = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::v4i32, N0);
9586 N1 = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::v4i32, N1);
9587 N0 = DAG.getNode(ISD::SINT_TO_FP, dl, MVT::v4f32, N0);
9588 N1 = DAG.getNode(ISD::SINT_TO_FP, dl, MVT::v4f32, N1);
9589
9590 // Use reciprocal estimate and one refinement step.
9591 // float4 recip = vrecpeq_f32(yf);
9592 // recip *= vrecpsq_f32(yf, recip);
9593 N2 = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, MVT::v4f32,
9594 DAG.getConstant(Intrinsic::arm_neon_vrecpe, dl, MVT::i32),
9595 N1);
9596 N1 = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, MVT::v4f32,
9597 DAG.getConstant(Intrinsic::arm_neon_vrecps, dl, MVT::i32),
9598 N1, N2);
9599 N2 = DAG.getNode(ISD::FMUL, dl, MVT::v4f32, N1, N2);
9600 // Because short has a smaller range than ushort, we can actually get away
9601 // with only a single newton step. This requires that we use a weird bias
9602 // of 89, however (again, this has been exhaustively tested).
9603 // float4 result = as_float4(as_int4(xf*recip) + 0x89);
9604 N0 = DAG.getNode(ISD::FMUL, dl, MVT::v4f32, N0, N2);
9605 N0 = DAG.getNode(ISD::BITCAST, dl, MVT::v4i32, N0);
9606 N1 = DAG.getConstant(0x89, dl, MVT::v4i32);
9607 N0 = DAG.getNode(ISD::ADD, dl, MVT::v4i32, N0, N1);
9608 N0 = DAG.getNode(ISD::BITCAST, dl, MVT::v4f32, N0);
9609 // Convert back to integer and return.
9610 // return vmovn_s32(vcvt_s32_f32(result));
9611 N0 = DAG.getNode(ISD::FP_TO_SINT, dl, MVT::v4i32, N0);
9612 N0 = DAG.getNode(ISD::TRUNCATE, dl, MVT::v4i16, N0);
9613 return N0;
9614}
9615
9617 const ARMSubtarget *ST) {
9618 EVT VT = Op.getValueType();
9619 assert((VT == MVT::v4i16 || VT == MVT::v8i8) &&
9620 "unexpected type for custom-lowering ISD::SDIV");
9621
9622 SDLoc dl(Op);
9623 SDValue N0 = Op.getOperand(0);
9624 SDValue N1 = Op.getOperand(1);
9625 SDValue N2, N3;
9626
9627 if (VT == MVT::v8i8) {
9628 N0 = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::v8i16, N0);
9629 N1 = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::v8i16, N1);
9630
9631 N2 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, MVT::v4i16, N0,
9632 DAG.getIntPtrConstant(4, dl));
9633 N3 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, MVT::v4i16, N1,
9634 DAG.getIntPtrConstant(4, dl));
9635 N0 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, MVT::v4i16, N0,
9636 DAG.getIntPtrConstant(0, dl));
9637 N1 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, MVT::v4i16, N1,
9638 DAG.getIntPtrConstant(0, dl));
9639
9640 N0 = LowerSDIV_v4i8(N0, N1, dl, DAG); // v4i16
9641 N2 = LowerSDIV_v4i8(N2, N3, dl, DAG); // v4i16
9642
9643 N0 = DAG.getNode(ISD::CONCAT_VECTORS, dl, MVT::v8i16, N0, N2);
9644 N0 = LowerCONCAT_VECTORS(N0, DAG, ST);
9645
9646 N0 = DAG.getNode(ISD::TRUNCATE, dl, MVT::v8i8, N0);
9647 return N0;
9648 }
9649 return LowerSDIV_v4i16(N0, N1, dl, DAG);
9650}
9651
9653 const ARMSubtarget *ST) {
9654 // TODO: Should this propagate fast-math-flags?
9655 EVT VT = Op.getValueType();
9656 assert((VT == MVT::v4i16 || VT == MVT::v8i8) &&
9657 "unexpected type for custom-lowering ISD::UDIV");
9658
9659 SDLoc dl(Op);
9660 SDValue N0 = Op.getOperand(0);
9661 SDValue N1 = Op.getOperand(1);
9662 SDValue N2, N3;
9663
9664 if (VT == MVT::v8i8) {
9665 N0 = DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::v8i16, N0);
9666 N1 = DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::v8i16, N1);
9667
9668 N2 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, MVT::v4i16, N0,
9669 DAG.getIntPtrConstant(4, dl));
9670 N3 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, MVT::v4i16, N1,
9671 DAG.getIntPtrConstant(4, dl));
9672 N0 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, MVT::v4i16, N0,
9673 DAG.getIntPtrConstant(0, dl));
9674 N1 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, MVT::v4i16, N1,
9675 DAG.getIntPtrConstant(0, dl));
9676
9677 N0 = LowerSDIV_v4i16(N0, N1, dl, DAG); // v4i16
9678 N2 = LowerSDIV_v4i16(N2, N3, dl, DAG); // v4i16
9679
9680 N0 = DAG.getNode(ISD::CONCAT_VECTORS, dl, MVT::v8i16, N0, N2);
9681 N0 = LowerCONCAT_VECTORS(N0, DAG, ST);
9682
9683 N0 = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, MVT::v8i8,
9684 DAG.getConstant(Intrinsic::arm_neon_vqmovnsu, dl,
9685 MVT::i32),
9686 N0);
9687 return N0;
9688 }
9689
9690 // v4i16 sdiv ... Convert to float.
9691 // float4 yf = vcvt_f32_s32(vmovl_u16(y));
9692 // float4 xf = vcvt_f32_s32(vmovl_u16(x));
9693 N0 = DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::v4i32, N0);
9694 N1 = DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::v4i32, N1);
9695 N0 = DAG.getNode(ISD::SINT_TO_FP, dl, MVT::v4f32, N0);
9696 SDValue BN1 = DAG.getNode(ISD::SINT_TO_FP, dl, MVT::v4f32, N1);
9697
9698 // Use reciprocal estimate and two refinement steps.
9699 // float4 recip = vrecpeq_f32(yf);
9700 // recip *= vrecpsq_f32(yf, recip);
9701 // recip *= vrecpsq_f32(yf, recip);
9702 N2 = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, MVT::v4f32,
9703 DAG.getConstant(Intrinsic::arm_neon_vrecpe, dl, MVT::i32),
9704 BN1);
9705 N1 = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, MVT::v4f32,
9706 DAG.getConstant(Intrinsic::arm_neon_vrecps, dl, MVT::i32),
9707 BN1, N2);
9708 N2 = DAG.getNode(ISD::FMUL, dl, MVT::v4f32, N1, N2);
9709 N1 = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, MVT::v4f32,
9710 DAG.getConstant(Intrinsic::arm_neon_vrecps, dl, MVT::i32),
9711 BN1, N2);
9712 N2 = DAG.getNode(ISD::FMUL, dl, MVT::v4f32, N1, N2);
9713 // Simply multiplying by the reciprocal estimate can leave us a few ulps
9714 // too low, so we add 2 ulps (exhaustive testing shows that this is enough,
9715 // and that it will never cause us to return an answer too large).
9716 // float4 result = as_float4(as_int4(xf*recip) + 2);
9717 N0 = DAG.getNode(ISD::FMUL, dl, MVT::v4f32, N0, N2);
9718 N0 = DAG.getNode(ISD::BITCAST, dl, MVT::v4i32, N0);
9719 N1 = DAG.getConstant(2, dl, MVT::v4i32);
9720 N0 = DAG.getNode(ISD::ADD, dl, MVT::v4i32, N0, N1);
9721 N0 = DAG.getNode(ISD::BITCAST, dl, MVT::v4f32, N0);
9722 // Convert back to integer and return.
9723 // return vmovn_u32(vcvt_s32_f32(result));
9724 N0 = DAG.getNode(ISD::FP_TO_SINT, dl, MVT::v4i32, N0);
9725 N0 = DAG.getNode(ISD::TRUNCATE, dl, MVT::v4i16, N0);
9726 return N0;
9727}
9728
9730 unsigned Opcode, bool IsSigned) {
9731 EVT VT0 = Op.getValue(0).getValueType();
9732 EVT VT1 = Op.getValue(1).getValueType();
9733
9734 bool InvertCarry = Opcode == ARMISD::SUBE;
9735 SDValue OpLHS = Op.getOperand(0);
9736 SDValue OpRHS = Op.getOperand(1);
9737 SDValue OpCarryIn = valueToCarryFlag(Op.getOperand(2), DAG, InvertCarry);
9738
9739 SDLoc DL(Op);
9740
9741 SDValue Result = DAG.getNode(Opcode, DL, DAG.getVTList(VT0, MVT::i32), OpLHS,
9742 OpRHS, OpCarryIn);
9743
9744 SDValue OutFlag =
9745 IsSigned ? overflowFlagToValue(Result.getValue(1), VT1, DAG)
9746 : carryFlagToValue(Result.getValue(1), VT1, DAG, InvertCarry);
9747
9748 return DAG.getMergeValues({Result, OutFlag}, DL);
9749}
9750
9751SDValue ARMTargetLowering::LowerWindowsDIVLibCall(SDValue Op, SelectionDAG &DAG,
9752 bool Signed,
9753 SDValue &Chain) const {
9754 EVT VT = Op.getValueType();
9755 assert((VT == MVT::i32 || VT == MVT::i64) &&
9756 "unexpected type for custom lowering DIV");
9757 SDLoc dl(Op);
9758
9759 const auto &DL = DAG.getDataLayout();
9760 RTLIB::Libcall LC;
9761 if (Signed)
9762 LC = VT == MVT::i32 ? RTLIB::SDIVREM_I32 : RTLIB::SDIVREM_I64;
9763 else
9764 LC = VT == MVT::i32 ? RTLIB::UDIVREM_I32 : RTLIB::UDIVREM_I64;
9765
9766 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
9767 SDValue ES = DAG.getExternalSymbol(LCImpl, getPointerTy(DL));
9768
9770
9771 for (auto AI : {1, 0}) {
9772 SDValue Operand = Op.getOperand(AI);
9773 Args.emplace_back(Operand,
9774 Operand.getValueType().getTypeForEVT(*DAG.getContext()));
9775 }
9776
9777 CallLoweringInfo CLI(DAG);
9778 CLI.setDebugLoc(dl).setChain(Chain).setCallee(
9780 VT.getTypeForEVT(*DAG.getContext()), ES, std::move(Args));
9781
9782 return LowerCallTo(CLI).first;
9783}
9784
9785// This is a code size optimisation: return the original SDIV node to
9786// DAGCombiner when we don't want to expand SDIV into a sequence of
9787// instructions, and an empty node otherwise which will cause the
9788// SDIV to be expanded in DAGCombine.
9789SDValue
9790ARMTargetLowering::BuildSDIVPow2(SDNode *N, const APInt &Divisor,
9791 SelectionDAG &DAG,
9792 SmallVectorImpl<SDNode *> &Created) const {
9793 // TODO: Support SREM
9794 if (N->getOpcode() != ISD::SDIV)
9795 return SDValue();
9796
9797 const auto &ST = DAG.getSubtarget<ARMSubtarget>();
9798 const bool MinSize = ST.hasMinSize();
9799 const bool HasDivide = ST.isThumb() ? ST.hasDivideInThumbMode()
9800 : ST.hasDivideInARMMode();
9801
9802 // Don't touch vector types; rewriting this may lead to scalarizing
9803 // the int divs.
9804 if (N->getOperand(0).getValueType().isVector())
9805 return SDValue();
9806
9807 // Bail if MinSize is not set, and also for both ARM and Thumb mode we need
9808 // hwdiv support for this to be really profitable.
9809 if (!(MinSize && HasDivide))
9810 return SDValue();
9811
9812 // ARM mode is a bit simpler than Thumb: we can handle large power
9813 // of 2 immediates with 1 mov instruction; no further checks required,
9814 // just return the sdiv node.
9815 if (!ST.isThumb())
9816 return SDValue(N, 0);
9817
9818 // In Thumb mode, immediates larger than 128 need a wide 4-byte MOV,
9819 // and thus lose the code size benefits of a MOVS that requires only 2.
9820 // TargetTransformInfo and 'getIntImmCodeSizeCost' could be helpful here,
9821 // but as it's doing exactly this, it's not worth the trouble to get TTI.
9822 if (Divisor.sgt(128))
9823 return SDValue();
9824
9825 return SDValue(N, 0);
9826}
9827
9828SDValue ARMTargetLowering::LowerDIV_Windows(SDValue Op, SelectionDAG &DAG,
9829 bool Signed) const {
9830 assert(Op.getValueType() == MVT::i32 &&
9831 "unexpected type for custom lowering DIV");
9832 SDLoc dl(Op);
9833
9834 SDValue DBZCHK = DAG.getNode(ARMISD::WIN__DBZCHK, dl, MVT::Other,
9835 DAG.getEntryNode(), Op.getOperand(1));
9836
9837 return LowerWindowsDIVLibCall(Op, DAG, Signed, DBZCHK);
9838}
9839
9841 SDLoc DL(N);
9842 SDValue Op = N->getOperand(1);
9843 if (N->getValueType(0) == MVT::i32)
9844 return DAG.getNode(ARMISD::WIN__DBZCHK, DL, MVT::Other, InChain, Op);
9845 SDValue Lo, Hi;
9846 std::tie(Lo, Hi) = DAG.SplitScalar(Op, DL, MVT::i32, MVT::i32);
9847 return DAG.getNode(ARMISD::WIN__DBZCHK, DL, MVT::Other, InChain,
9848 DAG.getNode(ISD::OR, DL, MVT::i32, Lo, Hi));
9849}
9850
9851void ARMTargetLowering::ExpandDIV_Windows(
9852 SDValue Op, SelectionDAG &DAG, bool Signed,
9854 const auto &DL = DAG.getDataLayout();
9855
9856 assert(Op.getValueType() == MVT::i64 &&
9857 "unexpected type for custom lowering DIV");
9858 SDLoc dl(Op);
9859
9860 SDValue DBZCHK = WinDBZCheckDenominator(DAG, Op.getNode(), DAG.getEntryNode());
9861
9862 SDValue Result = LowerWindowsDIVLibCall(Op, DAG, Signed, DBZCHK);
9863
9864 SDValue Lower = DAG.getNode(ISD::TRUNCATE, dl, MVT::i32, Result);
9865 SDValue Upper = DAG.getNode(ISD::SRL, dl, MVT::i64, Result,
9866 DAG.getConstant(32, dl, getPointerTy(DL)));
9867 Upper = DAG.getNode(ISD::TRUNCATE, dl, MVT::i32, Upper);
9868
9869 Results.push_back(DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Lower, Upper));
9870}
9871
9872std::pair<SDValue, SDValue>
9873ARMTargetLowering::LowerAEABIUnalignedLoad(SDValue Op,
9874 SelectionDAG &DAG) const {
9875 // If we have an unaligned load from a i32 or i64 that would normally be
9876 // split into separate ldrb's, we can use the __aeabi_uread4/__aeabi_uread8
9877 // functions instead.
9878 LoadSDNode *LD = cast<LoadSDNode>(Op.getNode());
9879 EVT MemVT = LD->getMemoryVT();
9880 if (MemVT != MVT::i32 && MemVT != MVT::i64)
9881 return std::make_pair(SDValue(), SDValue());
9882
9883 const auto &MF = DAG.getMachineFunction();
9884 unsigned AS = LD->getAddressSpace();
9885 Align Alignment = LD->getAlign();
9886 const DataLayout &DL = DAG.getDataLayout();
9887 bool AllowsUnaligned = Subtarget->allowsUnalignedMem();
9888 RTLIB::Libcall LC =
9889 (MemVT == MVT::i32) ? RTLIB::AEABI_UREAD4 : RTLIB::AEABI_UREAD8;
9890
9891 if (MF.getFunction().hasMinSize() && !AllowsUnaligned &&
9892 Alignment <= llvm::Align(2) && DAG.getLibcalls().getLibcallImpl(LC)) {
9893 MakeLibCallOptions Opts;
9894 SDLoc dl(Op);
9895
9896 auto Pair = makeLibCall(DAG, LC, MemVT.getSimpleVT(), LD->getBasePtr(),
9897 Opts, dl, LD->getChain());
9898
9899 // If necessary, extend the node to 64bit
9900 if (LD->getExtensionType() != ISD::NON_EXTLOAD) {
9901 unsigned ExtType = LD->getExtensionType() == ISD::SEXTLOAD
9904 SDValue EN = DAG.getNode(ExtType, dl, LD->getValueType(0), Pair.first);
9905 Pair.first = EN;
9906 }
9907 return Pair;
9908 }
9909
9910 // Default expand to individual loads
9911 if (!allowsMemoryAccess(*DAG.getContext(), DL, MemVT, AS, Alignment))
9912 return expandUnalignedLoad(LD, DAG);
9913 return std::make_pair(SDValue(), SDValue());
9914}
9915
9916SDValue ARMTargetLowering::LowerAEABIUnalignedStore(SDValue Op,
9917 SelectionDAG &DAG) const {
9918 // If we have an unaligned store to a i32 or i64 that would normally be
9919 // split into separate ldrb's, we can use the __aeabi_uwrite4/__aeabi_uwrite8
9920 // functions instead.
9921 StoreSDNode *ST = cast<StoreSDNode>(Op.getNode());
9922 EVT MemVT = ST->getMemoryVT();
9923 if (MemVT != MVT::i32 && MemVT != MVT::i64)
9924 return SDValue();
9925
9926 const auto &MF = DAG.getMachineFunction();
9927 unsigned AS = ST->getAddressSpace();
9928 Align Alignment = ST->getAlign();
9929 const DataLayout &DL = DAG.getDataLayout();
9930 bool AllowsUnaligned = Subtarget->allowsUnalignedMem();
9931 RTLIB::Libcall LC =
9932 (MemVT == MVT::i32) ? RTLIB::AEABI_UWRITE4 : RTLIB::AEABI_UWRITE8;
9933
9934 if (MF.getFunction().hasMinSize() && !AllowsUnaligned &&
9935 Alignment <= llvm::Align(2) && DAG.getLibcalls().getLibcallImpl(LC)) {
9936
9937 SDLoc dl(Op);
9938
9939 // If necessary, trunc the value to 32bit
9940 SDValue StoreVal = ST->getOperand(1);
9941 if (ST->isTruncatingStore())
9942 StoreVal = DAG.getNode(ISD::TRUNCATE, dl, MemVT, ST->getOperand(1));
9943
9944 MakeLibCallOptions Opts;
9945 auto CallResult =
9946 makeLibCall(DAG, LC, MVT::isVoid, {StoreVal, ST->getBasePtr()}, Opts,
9947 dl, ST->getChain());
9948
9949 return CallResult.second;
9950 }
9951
9952 // Default expand to individual stores
9953 if (!allowsMemoryAccess(*DAG.getContext(), DL, MemVT, AS, Alignment))
9954 return expandUnalignedStore(ST, DAG);
9955 return SDValue();
9956}
9957
9959 LoadSDNode *LD = cast<LoadSDNode>(Op.getNode());
9960 EVT MemVT = LD->getMemoryVT();
9961 assert((MemVT == MVT::v2i1 || MemVT == MVT::v4i1 || MemVT == MVT::v8i1 ||
9962 MemVT == MVT::v16i1) &&
9963 "Expected a predicate type!");
9964 assert(MemVT == Op.getValueType());
9965 assert(LD->getExtensionType() == ISD::NON_EXTLOAD &&
9966 "Expected a non-extending load");
9967 assert(LD->isUnindexed() && "Expected a unindexed load");
9968
9969 // The basic MVE VLDR on a v2i1/v4i1/v8i1 actually loads the entire 16bit
9970 // predicate, with the "v4i1" bits spread out over the 16 bits loaded. We
9971 // need to make sure that 8/4/2 bits are actually loaded into the correct
9972 // place, which means loading the value and then shuffling the values into
9973 // the bottom bits of the predicate.
9974 // Equally, VLDR for an v16i1 will actually load 32bits (so will be incorrect
9975 // for BE).
9976 // Speaking of BE, apparently the rest of llvm will assume a reverse order to
9977 // a natural VMSR(load), so needs to be reversed.
9978
9979 SDLoc dl(Op);
9980 SDValue Load = DAG.getExtLoad(
9981 ISD::EXTLOAD, dl, MVT::i32, LD->getChain(), LD->getBasePtr(),
9983 LD->getMemOperand());
9984 SDValue Val = Load;
9985 if (DAG.getDataLayout().isBigEndian())
9986 Val = DAG.getNode(ISD::SRL, dl, MVT::i32,
9987 DAG.getNode(ISD::BITREVERSE, dl, MVT::i32, Load),
9988 DAG.getConstant(32 - MemVT.getSizeInBits(), dl, MVT::i32));
9989 SDValue Pred = DAG.getNode(ARMISD::PREDICATE_CAST, dl, MVT::v16i1, Val);
9990 if (MemVT != MVT::v16i1)
9991 Pred = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, MemVT, Pred,
9992 DAG.getConstant(0, dl, MVT::i32));
9993 return DAG.getMergeValues({Pred, Load.getValue(1)}, dl);
9994}
9995
9996void ARMTargetLowering::LowerLOAD(SDNode *N, SmallVectorImpl<SDValue> &Results,
9997 SelectionDAG &DAG) const {
9998 LoadSDNode *LD = cast<LoadSDNode>(N);
9999 EVT MemVT = LD->getMemoryVT();
10000
10001 if (MemVT == MVT::i64 && Subtarget->hasV5TEOps() &&
10002 !Subtarget->isThumb1Only() && LD->isVolatile() &&
10003 LD->getAlign() >= Subtarget->getDualLoadStoreAlignment()) {
10004 assert(LD->isUnindexed() && "Loads should be unindexed at this point.");
10005 SDLoc dl(N);
10006 SDValue Result = DAG.getMemIntrinsicNode(
10007 ARMISD::LDRD, dl, DAG.getVTList({MVT::i32, MVT::i32, MVT::Other}),
10008 {LD->getChain(), LD->getBasePtr()}, MemVT, LD->getMemOperand());
10009 SDValue Lo = Result.getValue(DAG.getDataLayout().isLittleEndian() ? 0 : 1);
10010 SDValue Hi = Result.getValue(DAG.getDataLayout().isLittleEndian() ? 1 : 0);
10011 SDValue Pair = DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Lo, Hi);
10012 Results.append({Pair, Result.getValue(2)});
10013 } else if (MemVT == MVT::i32 || MemVT == MVT::i64) {
10014 auto Pair = LowerAEABIUnalignedLoad(SDValue(N, 0), DAG);
10015 if (Pair.first) {
10016 Results.push_back(Pair.first);
10017 Results.push_back(Pair.second);
10018 }
10019 }
10020}
10021
10023 StoreSDNode *ST = cast<StoreSDNode>(Op.getNode());
10024 EVT MemVT = ST->getMemoryVT();
10025 assert((MemVT == MVT::v2i1 || MemVT == MVT::v4i1 || MemVT == MVT::v8i1 ||
10026 MemVT == MVT::v16i1) &&
10027 "Expected a predicate type!");
10028 assert(MemVT == ST->getValue().getValueType());
10029 assert(!ST->isTruncatingStore() && "Expected a non-extending store");
10030 assert(ST->isUnindexed() && "Expected a unindexed store");
10031
10032 // Only store the v2i1 or v4i1 or v8i1 worth of bits, via a buildvector with
10033 // top bits unset and a scalar store.
10034 SDLoc dl(Op);
10035 SDValue Build = ST->getValue();
10036 if (MemVT != MVT::v16i1) {
10038 for (unsigned I = 0; I < MemVT.getVectorNumElements(); I++) {
10039 unsigned Elt = DAG.getDataLayout().isBigEndian()
10040 ? MemVT.getVectorNumElements() - I - 1
10041 : I;
10042 Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i32, Build,
10043 DAG.getConstant(Elt, dl, MVT::i32)));
10044 }
10045 for (unsigned I = MemVT.getVectorNumElements(); I < 16; I++)
10046 Ops.push_back(DAG.getUNDEF(MVT::i32));
10047 Build = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v16i1, Ops);
10048 }
10049 SDValue GRP = DAG.getNode(ARMISD::PREDICATE_CAST, dl, MVT::i32, Build);
10050 if (MemVT == MVT::v16i1 && DAG.getDataLayout().isBigEndian())
10051 GRP = DAG.getNode(ISD::SRL, dl, MVT::i32,
10052 DAG.getNode(ISD::BITREVERSE, dl, MVT::i32, GRP),
10053 DAG.getConstant(16, dl, MVT::i32));
10054 return DAG.getTruncStore(
10055 ST->getChain(), dl, GRP, ST->getBasePtr(),
10057 ST->getMemOperand());
10058}
10059
10060SDValue ARMTargetLowering::LowerSTORE(SDValue Op, SelectionDAG &DAG,
10061 const ARMSubtarget *Subtarget) const {
10062 StoreSDNode *ST = cast<StoreSDNode>(Op.getNode());
10063 EVT MemVT = ST->getMemoryVT();
10064
10065 if (MemVT == MVT::i64 && Subtarget->hasV5TEOps() &&
10066 !Subtarget->isThumb1Only() && ST->isVolatile() &&
10067 ST->getAlign() >= Subtarget->getDualLoadStoreAlignment()) {
10068 assert(ST->isUnindexed() && "Stores should be unindexed at this point.");
10069 SDNode *N = Op.getNode();
10070 SDLoc dl(N);
10071
10072 SDValue Lo = DAG.getNode(
10073 ISD::EXTRACT_ELEMENT, dl, MVT::i32, ST->getValue(),
10074 DAG.getTargetConstant(DAG.getDataLayout().isLittleEndian() ? 0 : 1, dl,
10075 MVT::i32));
10076 SDValue Hi = DAG.getNode(
10077 ISD::EXTRACT_ELEMENT, dl, MVT::i32, ST->getValue(),
10078 DAG.getTargetConstant(DAG.getDataLayout().isLittleEndian() ? 1 : 0, dl,
10079 MVT::i32));
10080
10081 return DAG.getMemIntrinsicNode(ARMISD::STRD, dl, DAG.getVTList(MVT::Other),
10082 {ST->getChain(), Lo, Hi, ST->getBasePtr()},
10083 MemVT, ST->getMemOperand());
10084 } else if (Subtarget->hasMVEIntegerOps() &&
10085 ((MemVT == MVT::v2i1 || MemVT == MVT::v4i1 || MemVT == MVT::v8i1 ||
10086 MemVT == MVT::v16i1))) {
10087 return LowerPredicateStore(Op, DAG);
10088 } else if (MemVT == MVT::i32 || MemVT == MVT::i64) {
10089 return LowerAEABIUnalignedStore(Op, DAG);
10090 }
10091 return SDValue();
10092}
10093
10094static bool isZeroVector(SDValue N) {
10095 return (ISD::isBuildVectorAllZeros(N.getNode()) ||
10096 (N->getOpcode() == ARMISD::VMOVIMM &&
10097 isNullConstant(N->getOperand(0))));
10098}
10099
10102 MVT VT = Op.getSimpleValueType();
10103 SDValue Mask = N->getMask();
10104 SDValue PassThru = N->getPassThru();
10105 SDLoc dl(Op);
10106
10107 if (isZeroVector(PassThru))
10108 return Op;
10109
10110 // MVE Masked loads use zero as the passthru value. Here we convert undef to
10111 // zero too, and other values are lowered to a select.
10112 SDValue ZeroVec = DAG.getNode(ARMISD::VMOVIMM, dl, VT,
10113 DAG.getTargetConstant(0, dl, MVT::i32));
10114 SDValue NewLoad = DAG.getMaskedLoad(
10115 VT, dl, N->getChain(), N->getBasePtr(), N->getOffset(), Mask, ZeroVec,
10116 N->getMemoryVT(), N->getMemOperand(), N->getAddressingMode(),
10117 N->getExtensionType(), N->isExpandingLoad());
10118 SDValue Combo = NewLoad;
10119 bool PassThruIsCastZero = (PassThru.getOpcode() == ISD::BITCAST ||
10120 PassThru.getOpcode() == ARMISD::VECTOR_REG_CAST) &&
10121 isZeroVector(PassThru->getOperand(0));
10122 if (!PassThru.isUndef() && !PassThruIsCastZero)
10123 Combo = DAG.getNode(ISD::VSELECT, dl, VT, Mask, NewLoad, PassThru);
10124 return DAG.getMergeValues({Combo, NewLoad.getValue(1)}, dl);
10125}
10126
10128 const ARMSubtarget *ST) {
10129 if (!ST->hasMVEIntegerOps())
10130 return SDValue();
10131
10132 SDLoc dl(Op);
10133 unsigned BaseOpcode = 0;
10134 switch (Op->getOpcode()) {
10135 default: llvm_unreachable("Expected VECREDUCE opcode");
10136 case ISD::VECREDUCE_FADD: BaseOpcode = ISD::FADD; break;
10137 case ISD::VECREDUCE_FMUL: BaseOpcode = ISD::FMUL; break;
10138 case ISD::VECREDUCE_MUL: BaseOpcode = ISD::MUL; break;
10139 case ISD::VECREDUCE_AND: BaseOpcode = ISD::AND; break;
10140 case ISD::VECREDUCE_OR: BaseOpcode = ISD::OR; break;
10141 case ISD::VECREDUCE_XOR: BaseOpcode = ISD::XOR; break;
10142 case ISD::VECREDUCE_FMAX: BaseOpcode = ISD::FMAXNUM; break;
10143 case ISD::VECREDUCE_FMIN: BaseOpcode = ISD::FMINNUM; break;
10144 }
10145
10146 SDValue Op0 = Op->getOperand(0);
10147 EVT VT = Op0.getValueType();
10148 EVT EltVT = VT.getVectorElementType();
10149 unsigned NumElts = VT.getVectorNumElements();
10150 unsigned NumActiveLanes = NumElts;
10151
10152 assert((NumActiveLanes == 16 || NumActiveLanes == 8 || NumActiveLanes == 4 ||
10153 NumActiveLanes == 2) &&
10154 "Only expected a power 2 vector size");
10155
10156 // Use Mul(X, Rev(X)) until 4 items remain. Going down to 4 vector elements
10157 // allows us to easily extract vector elements from the lanes.
10158 while (NumActiveLanes > 4) {
10159 unsigned RevOpcode = NumActiveLanes == 16 ? ARMISD::VREV16 : ARMISD::VREV32;
10160 SDValue Rev = DAG.getNode(RevOpcode, dl, VT, Op0);
10161 Op0 = DAG.getNode(BaseOpcode, dl, VT, Op0, Rev);
10162 NumActiveLanes /= 2;
10163 }
10164
10165 SDValue Res;
10166 if (NumActiveLanes == 4) {
10167 // The remaining 4 elements are summed sequentially
10168 SDValue Ext0 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, Op0,
10169 DAG.getConstant(0 * NumElts / 4, dl, MVT::i32));
10170 SDValue Ext1 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, Op0,
10171 DAG.getConstant(1 * NumElts / 4, dl, MVT::i32));
10172 SDValue Ext2 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, Op0,
10173 DAG.getConstant(2 * NumElts / 4, dl, MVT::i32));
10174 SDValue Ext3 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, Op0,
10175 DAG.getConstant(3 * NumElts / 4, dl, MVT::i32));
10176 SDValue Res0 = DAG.getNode(BaseOpcode, dl, EltVT, Ext0, Ext1, Op->getFlags());
10177 SDValue Res1 = DAG.getNode(BaseOpcode, dl, EltVT, Ext2, Ext3, Op->getFlags());
10178 Res = DAG.getNode(BaseOpcode, dl, EltVT, Res0, Res1, Op->getFlags());
10179 } else {
10180 SDValue Ext0 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, Op0,
10181 DAG.getConstant(0, dl, MVT::i32));
10182 SDValue Ext1 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, Op0,
10183 DAG.getConstant(1, dl, MVT::i32));
10184 Res = DAG.getNode(BaseOpcode, dl, EltVT, Ext0, Ext1, Op->getFlags());
10185 }
10186
10187 // Result type may be wider than element type.
10188 if (EltVT != Op->getValueType(0))
10189 Res = DAG.getNode(ISD::ANY_EXTEND, dl, Op->getValueType(0), Res);
10190 return Res;
10191}
10192
10194 const ARMSubtarget *ST) {
10195 if (!ST->hasMVEFloatOps())
10196 return SDValue();
10197 return LowerVecReduce(Op, DAG, ST);
10198}
10199
10201 const ARMSubtarget *ST) {
10202 if (!ST->hasNEON())
10203 return SDValue();
10204
10205 SDLoc dl(Op);
10206 SDValue Op0 = Op->getOperand(0);
10207 EVT VT = Op0.getValueType();
10208 EVT EltVT = VT.getVectorElementType();
10209
10210 unsigned PairwiseIntrinsic = 0;
10211 switch (Op->getOpcode()) {
10212 default:
10213 llvm_unreachable("Expected VECREDUCE opcode");
10215 PairwiseIntrinsic = Intrinsic::arm_neon_vpminu;
10216 break;
10218 PairwiseIntrinsic = Intrinsic::arm_neon_vpmaxu;
10219 break;
10221 PairwiseIntrinsic = Intrinsic::arm_neon_vpmins;
10222 break;
10224 PairwiseIntrinsic = Intrinsic::arm_neon_vpmaxs;
10225 break;
10226 }
10227 SDValue PairwiseOp = DAG.getConstant(PairwiseIntrinsic, dl, MVT::i32);
10228
10229 unsigned NumElts = VT.getVectorNumElements();
10230 unsigned NumActiveLanes = NumElts;
10231
10232 assert((NumActiveLanes == 16 || NumActiveLanes == 8 || NumActiveLanes == 4 ||
10233 NumActiveLanes == 2) &&
10234 "Only expected a power 2 vector size");
10235
10236 // Split 128-bit vectors, since vpmin/max takes 2 64-bit vectors.
10237 if (VT.is128BitVector()) {
10238 SDValue Lo, Hi;
10239 std::tie(Lo, Hi) = DAG.SplitVector(Op0, dl);
10240 VT = Lo.getValueType();
10241 Op0 = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, VT, {PairwiseOp, Lo, Hi});
10242 NumActiveLanes /= 2;
10243 }
10244
10245 // Use pairwise reductions until one lane remains
10246 while (NumActiveLanes > 1) {
10247 Op0 = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, VT, {PairwiseOp, Op0, Op0});
10248 NumActiveLanes /= 2;
10249 }
10250
10251 SDValue Res = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, Op0,
10252 DAG.getConstant(0, dl, MVT::i32));
10253
10254 // Result type may be wider than element type.
10255 if (EltVT != Op.getValueType()) {
10256 unsigned Extend = 0;
10257 switch (Op->getOpcode()) {
10258 default:
10259 llvm_unreachable("Expected VECREDUCE opcode");
10262 Extend = ISD::ZERO_EXTEND;
10263 break;
10266 Extend = ISD::SIGN_EXTEND;
10267 break;
10268 }
10269 Res = DAG.getNode(Extend, dl, Op.getValueType(), Res);
10270 }
10271 return Res;
10272}
10273
10275 if (isStrongerThanMonotonic(cast<AtomicSDNode>(Op)->getSuccessOrdering()))
10276 // Acquire/Release load/store is not legal for targets without a dmb or
10277 // equivalent available.
10278 return SDValue();
10279
10280 // Monotonic load/store is legal for all targets.
10281 return Op;
10282}
10283
10286 SelectionDAG &DAG,
10287 const ARMSubtarget *Subtarget) {
10288 SDLoc DL(N);
10289 // Under Power Management extensions, the cycle-count is:
10290 // mrc p15, #0, <Rt>, c9, c13, #0
10291 SDValue Ops[] = { N->getOperand(0), // Chain
10292 DAG.getTargetConstant(Intrinsic::arm_mrc, DL, MVT::i32),
10293 DAG.getTargetConstant(15, DL, MVT::i32),
10294 DAG.getTargetConstant(0, DL, MVT::i32),
10295 DAG.getTargetConstant(9, DL, MVT::i32),
10296 DAG.getTargetConstant(13, DL, MVT::i32),
10297 DAG.getTargetConstant(0, DL, MVT::i32)
10298 };
10299
10300 SDValue Cycles32 = DAG.getNode(ISD::INTRINSIC_W_CHAIN, DL,
10301 DAG.getVTList(MVT::i32, MVT::Other), Ops);
10302 Results.push_back(DAG.getNode(ISD::BUILD_PAIR, DL, MVT::i64, Cycles32,
10303 DAG.getConstant(0, DL, MVT::i32)));
10304 Results.push_back(Cycles32.getValue(1));
10305}
10306
10308 SDValue V1) {
10309 SDLoc dl(V0.getNode());
10310 SDValue RegClass =
10311 DAG.getTargetConstant(ARM::GPRPairRegClassID, dl, MVT::i32);
10312 SDValue SubReg0 = DAG.getTargetConstant(ARM::gsub_0, dl, MVT::i32);
10313 SDValue SubReg1 = DAG.getTargetConstant(ARM::gsub_1, dl, MVT::i32);
10314 const SDValue Ops[] = {RegClass, V0, SubReg0, V1, SubReg1};
10315 return SDValue(
10316 DAG.getMachineNode(TargetOpcode::REG_SEQUENCE, dl, MVT::Untyped, Ops), 0);
10317}
10318
10320 SDLoc dl(V.getNode());
10321 auto [VLo, VHi] = DAG.SplitScalar(V, dl, MVT::i32, MVT::i32);
10322 bool isBigEndian = DAG.getDataLayout().isBigEndian();
10323 if (isBigEndian)
10324 std::swap(VLo, VHi);
10325 return createGPRPairNode2xi32(DAG, VLo, VHi);
10326}
10327
10330 SelectionDAG &DAG) {
10331 assert(N->getValueType(0) == MVT::i64 &&
10332 "AtomicCmpSwap on types less than 64 should be legal");
10333 SDValue Ops[] = {
10334 createGPRPairNode2xi32(DAG, N->getOperand(1),
10335 DAG.getUNDEF(MVT::i32)), // pointer, temp
10336 createGPRPairNodei64(DAG, N->getOperand(2)), // expected
10337 createGPRPairNodei64(DAG, N->getOperand(3)), // new
10338 N->getOperand(0), // chain in
10339 };
10340 SDNode *CmpSwap = DAG.getMachineNode(
10341 ARM::CMP_SWAP_64, SDLoc(N),
10342 DAG.getVTList(MVT::Untyped, MVT::Untyped, MVT::Other), Ops);
10343
10344 MachineMemOperand *MemOp = cast<MemSDNode>(N)->getMemOperand();
10345 DAG.setNodeMemRefs(cast<MachineSDNode>(CmpSwap), {MemOp});
10346
10347 bool isBigEndian = DAG.getDataLayout().isBigEndian();
10348
10349 SDValue Lo =
10350 DAG.getTargetExtractSubreg(isBigEndian ? ARM::gsub_1 : ARM::gsub_0,
10351 SDLoc(N), MVT::i32, SDValue(CmpSwap, 0));
10352 SDValue Hi =
10353 DAG.getTargetExtractSubreg(isBigEndian ? ARM::gsub_0 : ARM::gsub_1,
10354 SDLoc(N), MVT::i32, SDValue(CmpSwap, 0));
10355 Results.push_back(DAG.getNode(ISD::BUILD_PAIR, SDLoc(N), MVT::i64, Lo, Hi));
10356 Results.push_back(SDValue(CmpSwap, 2));
10357}
10358
10359SDValue ARMTargetLowering::LowerFSETCC(SDValue Op, SelectionDAG &DAG) const {
10360 SDLoc dl(Op);
10361 EVT VT = Op.getValueType();
10362 SDValue Chain = Op.getOperand(0);
10363 SDValue LHS = Op.getOperand(1);
10364 SDValue RHS = Op.getOperand(2);
10365 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(3))->get();
10366 bool IsSignaling = Op.getOpcode() == ISD::STRICT_FSETCCS;
10367
10368 // If we don't have instructions of this float type then soften to a libcall
10369 // and use SETCC instead.
10370 if (isUnsupportedFloatingType(LHS.getValueType())) {
10371 softenSetCCOperands(DAG, LHS.getValueType(), LHS, RHS, CC, dl, LHS, RHS,
10372 Chain, IsSignaling);
10373 if (!RHS.getNode()) {
10374 RHS = DAG.getConstant(0, dl, LHS.getValueType());
10375 CC = ISD::SETNE;
10376 }
10377 SDValue Result = DAG.getNode(ISD::SETCC, dl, VT, LHS, RHS,
10378 DAG.getCondCode(CC));
10379 return DAG.getMergeValues({Result, Chain}, dl);
10380 }
10381
10382 ARMCC::CondCodes CondCode, CondCode2;
10383 FPCCToARMCC(CC, CondCode, CondCode2);
10384
10385 SDValue True = DAG.getConstant(1, dl, VT);
10386 SDValue False = DAG.getConstant(0, dl, VT);
10387 SDValue ARMcc = DAG.getConstant(CondCode, dl, MVT::i32);
10388 SDValue Cmp = getVFPCmp(LHS, RHS, DAG, dl, IsSignaling);
10389 SDValue Result = getCMOV(dl, VT, False, True, ARMcc, Cmp, DAG);
10390 if (CondCode2 != ARMCC::AL) {
10391 ARMcc = DAG.getConstant(CondCode2, dl, MVT::i32);
10392 Result = getCMOV(dl, VT, Result, True, ARMcc, Cmp, DAG);
10393 }
10394 return DAG.getMergeValues({Result, Chain}, dl);
10395}
10396
10397SDValue ARMTargetLowering::LowerSPONENTRY(SDValue Op, SelectionDAG &DAG) const {
10398 MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();
10399
10400 EVT VT = getPointerTy(DAG.getDataLayout());
10401 int FI = MFI.CreateFixedObject(4, 0, false);
10402 return DAG.getFrameIndex(FI, VT);
10403}
10404
10405SDValue ARMTargetLowering::LowerFP_TO_BF16(SDValue Op,
10406 SelectionDAG &DAG) const {
10407 SDLoc DL(Op);
10408 MakeLibCallOptions CallOptions;
10409 MVT SVT = Op.getOperand(0).getSimpleValueType();
10410 RTLIB::Libcall LC = RTLIB::getFPROUND(SVT, MVT::bf16);
10411 SDValue Res =
10412 makeLibCall(DAG, LC, MVT::f32, Op.getOperand(0), CallOptions, DL).first;
10413 return DAG.getBitcast(MVT::i32, Res);
10414}
10415
10416SDValue ARMTargetLowering::LowerCMP(SDValue Op, SelectionDAG &DAG) const {
10417 SDLoc dl(Op);
10418 SDValue LHS = Op.getOperand(0);
10419 SDValue RHS = Op.getOperand(1);
10420
10421 // Determine if this is signed or unsigned comparison
10422 bool IsSigned = (Op.getOpcode() == ISD::SCMP);
10423
10424 // Special case for Thumb1 UCMP only
10425 if (!IsSigned && Subtarget->isThumb1Only()) {
10426 // For Thumb unsigned comparison, use this sequence:
10427 // subs r2, r0, r1 ; r2 = LHS - RHS, sets flags
10428 // sbc r2, r2 ; r2 = r2 - r2 - !carry
10429 // cmp r1, r0 ; compare RHS with LHS
10430 // sbc r1, r1 ; r1 = r1 - r1 - !carry
10431 // subs r0, r2, r1 ; r0 = r2 - r1 (final result)
10432
10433 // First subtraction: LHS - RHS
10434 SDValue Sub1WithFlags = DAG.getNode(
10435 ARMISD::SUBC, dl, DAG.getVTList(MVT::i32, FlagsVT), LHS, RHS);
10436 SDValue Sub1Result = Sub1WithFlags.getValue(0);
10437 SDValue Flags1 = Sub1WithFlags.getValue(1);
10438
10439 // SUBE: Sub1Result - Sub1Result - !carry
10440 // This gives 0 if LHS >= RHS (unsigned), -1 if LHS < RHS (unsigned)
10441 SDValue Sbc1 =
10442 DAG.getNode(ARMISD::SUBE, dl, DAG.getVTList(MVT::i32, FlagsVT),
10443 Sub1Result, Sub1Result, Flags1);
10444 SDValue Sbc1Result = Sbc1.getValue(0);
10445
10446 // Second comparison: RHS vs LHS (reverse comparison)
10447 SDValue CmpFlags = DAG.getNode(ARMISD::CMP, dl, FlagsVT, RHS, LHS);
10448
10449 // SUBE: RHS - RHS - !carry
10450 // This gives 0 if RHS <= LHS (unsigned), -1 if RHS > LHS (unsigned)
10451 SDValue Sbc2 = DAG.getNode(
10452 ARMISD::SUBE, dl, DAG.getVTList(MVT::i32, FlagsVT), RHS, RHS, CmpFlags);
10453 SDValue Sbc2Result = Sbc2.getValue(0);
10454
10455 // Final subtraction: Sbc1Result - Sbc2Result (no flags needed)
10456 SDValue Result =
10457 DAG.getNode(ISD::SUB, dl, MVT::i32, Sbc1Result, Sbc2Result);
10458 if (Op.getValueType() != MVT::i32)
10459 Result = DAG.getSExtOrTrunc(Result, dl, Op.getValueType());
10460
10461 return Result;
10462 }
10463
10464 // For the ARM assembly pattern:
10465 // subs r0, r0, r1 ; subtract RHS from LHS and set flags
10466 // movgt r0, #1 ; if LHS > RHS, set result to 1 (GT for signed, HI for
10467 // unsigned) mvnlt r0, #0 ; if LHS < RHS, set result to -1 (LT for
10468 // signed, LO for unsigned)
10469 // ; if LHS == RHS, result remains 0 from the subs
10470
10471 // Optimization: if RHS is a subtraction against 0, use ADDC instead of SUBC
10472 unsigned Opcode = ARMISD::SUBC;
10473
10474 // Check if RHS is a subtraction against 0: (0 - X)
10475 if (RHS.getOpcode() == ISD::SUB) {
10476 SDValue SubLHS = RHS.getOperand(0);
10477 SDValue SubRHS = RHS.getOperand(1);
10478
10479 // Check if it's 0 - X
10480 if (isNullConstant(SubLHS)) {
10481 bool CanUseAdd = false;
10482 if (IsSigned) {
10483 // For SCMP: only if X is known to never be INT_MIN (to avoid overflow)
10484 if (RHS->getFlags().hasNoSignedWrap() || !DAG.computeKnownBits(SubRHS)
10486 .isMinSignedValue()) {
10487 CanUseAdd = true;
10488 }
10489 } else {
10490 // For UCMP: only if X is known to never be zero
10491 if (DAG.isKnownNeverZero(SubRHS)) {
10492 CanUseAdd = true;
10493 }
10494 }
10495
10496 if (CanUseAdd) {
10497 Opcode = ARMISD::ADDC;
10498 RHS = SubRHS; // Replace RHS with X, so we do LHS + X instead of
10499 // LHS - (0 - X)
10500 }
10501 }
10502 }
10503
10504 // Generate the operation with flags
10505 SDValue OpWithFlags =
10506 DAG.getNode(Opcode, dl, DAG.getVTList(MVT::i32, FlagsVT), LHS, RHS);
10507
10508 SDValue OpResult = OpWithFlags.getValue(0);
10509 SDValue Flags = OpWithFlags.getValue(1);
10510
10511 // Constants for conditional moves
10512 SDValue One = DAG.getConstant(1, dl, MVT::i32);
10513 SDValue MinusOne = DAG.getAllOnesConstant(dl, MVT::i32);
10514
10515 // Select condition codes based on signed vs unsigned
10516 ARMCC::CondCodes GTCond = IsSigned ? ARMCC::GT : ARMCC::HI;
10517 ARMCC::CondCodes LTCond = IsSigned ? ARMCC::LT : ARMCC::LO;
10518
10519 // First conditional move: if greater than, set to 1
10520 SDValue GTCondValue = DAG.getConstant(GTCond, dl, MVT::i32);
10521 SDValue Result1 = DAG.getNode(ARMISD::CMOV, dl, MVT::i32, OpResult, One,
10522 GTCondValue, Flags);
10523
10524 // Second conditional move: if less than, set to -1
10525 SDValue LTCondValue = DAG.getConstant(LTCond, dl, MVT::i32);
10526 SDValue Result2 = DAG.getNode(ARMISD::CMOV, dl, MVT::i32, Result1, MinusOne,
10527 LTCondValue, Flags);
10528
10529 if (Op.getValueType() != MVT::i32)
10530 Result2 = DAG.getSExtOrTrunc(Result2, dl, Op.getValueType());
10531
10532 return Result2;
10533}
10534
10536 LLVM_DEBUG(dbgs() << "Lowering node: "; Op.dump());
10537 switch (Op.getOpcode()) {
10538 default: llvm_unreachable("Don't know how to custom lower this!");
10539 case ISD::WRITE_REGISTER: return LowerWRITE_REGISTER(Op, DAG);
10540 case ISD::ConstantPool: return LowerConstantPool(Op, DAG);
10541 case ISD::BlockAddress: return LowerBlockAddress(Op, DAG);
10542 case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG);
10543 case ISD::GlobalTLSAddress: return LowerGlobalTLSAddress(Op, DAG);
10544 case ISD::SELECT: return LowerSELECT(Op, DAG);
10545 case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG);
10546 case ISD::BRCOND: return LowerBRCOND(Op, DAG);
10547 case ISD::BR_CC: return LowerBR_CC(Op, DAG);
10548 case ISD::BR_JT: return LowerBR_JT(Op, DAG);
10549 case ISD::VASTART: return LowerVASTART(Op, DAG);
10550 case ISD::ATOMIC_FENCE: return LowerATOMIC_FENCE(Op, DAG, Subtarget);
10551 case ISD::PREFETCH: return LowerPREFETCH(Op, DAG, Subtarget);
10554 case ISD::SINT_TO_FP:
10555 case ISD::UINT_TO_FP: return LowerINT_TO_FP(Op, DAG);
10558 case ISD::FP_TO_SINT:
10559 case ISD::FP_TO_UINT: return LowerFP_TO_INT(Op, DAG);
10561 case ISD::FP_TO_UINT_SAT: return LowerFP_TO_INT_SAT(Op, DAG, Subtarget);
10562 case ISD::FCOPYSIGN: return LowerFCOPYSIGN(Op, DAG);
10563 case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG);
10564 case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG);
10565 case ISD::EH_SJLJ_SETJMP: return LowerEH_SJLJ_SETJMP(Op, DAG);
10566 case ISD::EH_SJLJ_LONGJMP: return LowerEH_SJLJ_LONGJMP(Op, DAG);
10567 case ISD::EH_SJLJ_SETUP_DISPATCH: return LowerEH_SJLJ_SETUP_DISPATCH(Op, DAG);
10568 case ISD::INTRINSIC_VOID: return LowerINTRINSIC_VOID(Op, DAG, Subtarget);
10569 case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG,
10570 Subtarget);
10571 case ISD::BITCAST: return ExpandBITCAST(Op.getNode(), DAG, Subtarget);
10572 case ISD::SHL:
10573 case ISD::SRL:
10574 case ISD::SRA: return LowerShift(Op.getNode(), DAG, Subtarget);
10575 case ISD::SREM: return LowerREM(Op.getNode(), DAG);
10576 case ISD::UREM: return LowerREM(Op.getNode(), DAG);
10577 case ISD::SHL_PARTS: return LowerShiftLeftParts(Op, DAG);
10578 case ISD::SRL_PARTS:
10579 case ISD::SRA_PARTS: return LowerShiftRightParts(Op, DAG);
10580 case ISD::CTTZ:
10581 case ISD::CTTZ_ZERO_POISON: return LowerCTTZ(Op.getNode(), DAG, Subtarget);
10582 case ISD::CTPOP: return LowerCTPOP(Op.getNode(), DAG, Subtarget);
10583 case ISD::SETCC: return LowerVSETCC(Op, DAG, Subtarget);
10584 case ISD::SETCCCARRY: return LowerSETCCCARRY(Op, DAG);
10585 case ISD::ConstantFP: return LowerConstantFP(Op, DAG, Subtarget);
10586 case ISD::BUILD_VECTOR: return LowerBUILD_VECTOR(Op, DAG, Subtarget);
10587 case ISD::VECTOR_SHUFFLE: return LowerVECTOR_SHUFFLE(Op, DAG, Subtarget);
10588 case ISD::EXTRACT_SUBVECTOR: return LowerEXTRACT_SUBVECTOR(Op, DAG, Subtarget);
10589 case ISD::INSERT_VECTOR_ELT: return LowerINSERT_VECTOR_ELT(Op, DAG);
10590 case ISD::EXTRACT_VECTOR_ELT: return LowerEXTRACT_VECTOR_ELT(Op, DAG, Subtarget);
10591 case ISD::CONCAT_VECTORS: return LowerCONCAT_VECTORS(Op, DAG, Subtarget);
10592 case ISD::TRUNCATE: return LowerTruncate(Op.getNode(), DAG, Subtarget);
10593 case ISD::SIGN_EXTEND:
10594 case ISD::ZERO_EXTEND: return LowerVectorExtend(Op.getNode(), DAG, Subtarget);
10595 case ISD::GET_ROUNDING: return LowerGET_ROUNDING(Op, DAG);
10596 case ISD::SET_ROUNDING: return LowerSET_ROUNDING(Op, DAG);
10597 case ISD::SET_FPMODE:
10598 return LowerSET_FPMODE(Op, DAG);
10599 case ISD::RESET_FPMODE:
10600 return LowerRESET_FPMODE(Op, DAG);
10601 case ISD::MUL: return LowerMUL(Op, DAG);
10602 case ISD::SDIV:
10603 if (getTargetMachine().getTargetTriple().isOSWindows() &&
10604 !Op.getValueType().isVector())
10605 return LowerDIV_Windows(Op, DAG, /* Signed */ true);
10606 return LowerSDIV(Op, DAG, Subtarget);
10607 case ISD::UDIV:
10608 if (getTargetMachine().getTargetTriple().isOSWindows() &&
10609 !Op.getValueType().isVector())
10610 return LowerDIV_Windows(Op, DAG, /* Signed */ false);
10611 return LowerUDIV(Op, DAG, Subtarget);
10612 case ISD::UADDO_CARRY:
10613 return LowerADDSUBO_CARRY(Op, DAG, ARMISD::ADDE, false /*unsigned*/);
10614 case ISD::USUBO_CARRY:
10615 return LowerADDSUBO_CARRY(Op, DAG, ARMISD::SUBE, false /*unsigned*/);
10616 case ISD::SADDO_CARRY:
10617 return LowerADDSUBO_CARRY(Op, DAG, ARMISD::ADDE, true /*signed*/);
10618 case ISD::SSUBO_CARRY:
10619 return LowerADDSUBO_CARRY(Op, DAG, ARMISD::SUBE, true /*signed*/);
10620 case ISD::UADDO:
10621 case ISD::USUBO:
10622 case ISD::UMULO:
10623 case ISD::SADDO:
10624 case ISD::SSUBO:
10625 case ISD::SMULO:
10626 return LowerALUO(Op, DAG);
10627 case ISD::SADDSAT:
10628 case ISD::SSUBSAT:
10629 case ISD::UADDSAT:
10630 case ISD::USUBSAT:
10631 return LowerADDSUBSAT(Op, DAG, Subtarget);
10632 case ISD::LOAD: {
10633 auto *LD = cast<LoadSDNode>(Op);
10634 EVT MemVT = LD->getMemoryVT();
10635 if (Subtarget->hasMVEIntegerOps() &&
10636 (MemVT == MVT::v2i1 || MemVT == MVT::v4i1 || MemVT == MVT::v8i1 ||
10637 MemVT == MVT::v16i1))
10638 return LowerPredicateLoad(Op, DAG);
10639
10640 auto Pair = LowerAEABIUnalignedLoad(Op, DAG);
10641 if (Pair.first)
10642 return DAG.getMergeValues({Pair.first, Pair.second}, SDLoc(Pair.first));
10643 return SDValue();
10644 }
10645 case ISD::STORE:
10646 return LowerSTORE(Op, DAG, Subtarget);
10647 case ISD::MLOAD:
10648 return LowerMLOAD(Op, DAG);
10649 case ISD::VECREDUCE_MUL:
10650 case ISD::VECREDUCE_AND:
10651 case ISD::VECREDUCE_OR:
10652 case ISD::VECREDUCE_XOR:
10653 return LowerVecReduce(Op, DAG, Subtarget);
10658 return LowerVecReduceF(Op, DAG, Subtarget);
10663 return LowerVecReduceMinMax(Op, DAG, Subtarget);
10664 case ISD::ATOMIC_LOAD:
10665 case ISD::ATOMIC_STORE:
10666 return LowerAtomicLoadStore(Op, DAG);
10667 case ISD::SDIVREM:
10668 case ISD::UDIVREM: return LowerDivRem(Op, DAG);
10670 if (getTargetMachine().getTargetTriple().isOSWindows())
10671 return LowerDYNAMIC_STACKALLOC(Op, DAG);
10672 llvm_unreachable("Don't know how to custom lower this!");
10674 case ISD::FP_ROUND: return LowerFP_ROUND(Op, DAG);
10676 case ISD::FP_EXTEND: return LowerFP_EXTEND(Op, DAG);
10677 case ISD::STRICT_FSETCC:
10678 case ISD::STRICT_FSETCCS: return LowerFSETCC(Op, DAG);
10679 case ISD::SPONENTRY:
10680 return LowerSPONENTRY(Op, DAG);
10681 case ISD::FP_TO_BF16:
10682 return LowerFP_TO_BF16(Op, DAG);
10683 case ARMISD::WIN__DBZCHK: return SDValue();
10684 case ISD::UCMP:
10685 case ISD::SCMP:
10686 return LowerCMP(Op, DAG);
10687 case ISD::ABS:
10688 return LowerABS(Op, DAG);
10689 case ISD::STRICT_LROUND:
10691 case ISD::STRICT_LRINT:
10692 case ISD::STRICT_LLRINT: {
10693 assert((Op.getOperand(1).getValueType() == MVT::f16 ||
10694 Op.getOperand(1).getValueType() == MVT::bf16) &&
10695 "Expected custom lowering of rounding operations only for f16");
10696 SDLoc DL(Op);
10697 SDValue Ext = DAG.getNode(ISD::STRICT_FP_EXTEND, DL, {MVT::f32, MVT::Other},
10698 {Op.getOperand(0), Op.getOperand(1)});
10699 return DAG.getNode(Op.getOpcode(), DL, {Op.getValueType(), MVT::Other},
10700 {Ext.getValue(1), Ext.getValue(0)});
10701 }
10702 }
10703}
10704
10706 SelectionDAG &DAG) {
10707 unsigned IntNo = N->getConstantOperandVal(0);
10708 unsigned Opc = 0;
10709 if (IntNo == Intrinsic::arm_smlald)
10710 Opc = ARMISD::SMLALD;
10711 else if (IntNo == Intrinsic::arm_smlaldx)
10712 Opc = ARMISD::SMLALDX;
10713 else if (IntNo == Intrinsic::arm_smlsld)
10714 Opc = ARMISD::SMLSLD;
10715 else if (IntNo == Intrinsic::arm_smlsldx)
10716 Opc = ARMISD::SMLSLDX;
10717 else
10718 return;
10719
10720 SDLoc dl(N);
10721 SDValue Lo, Hi;
10722 std::tie(Lo, Hi) = DAG.SplitScalar(N->getOperand(3), dl, MVT::i32, MVT::i32);
10723
10724 SDValue LongMul = DAG.getNode(Opc, dl,
10725 DAG.getVTList(MVT::i32, MVT::i32),
10726 N->getOperand(1), N->getOperand(2),
10727 Lo, Hi);
10728 Results.push_back(DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64,
10729 LongMul.getValue(0), LongMul.getValue(1)));
10730}
10731
10732/// ReplaceNodeResults - Replace the results of node with an illegal result
10733/// type with new values built out of custom code.
10736 SelectionDAG &DAG) const {
10737 SDValue Res;
10738 switch (N->getOpcode()) {
10739 default:
10740 llvm_unreachable("Don't know how to custom expand this!");
10741 case ISD::READ_REGISTER:
10743 break;
10744 case ISD::BITCAST:
10745 Res = ExpandBITCAST(N, DAG, Subtarget);
10746 break;
10747 case ISD::SRL:
10748 case ISD::SRA:
10749 case ISD::SHL:
10750 Res = Expand64BitShift(N, DAG, Subtarget);
10751 break;
10752 case ISD::SREM:
10753 case ISD::UREM:
10754 Res = LowerREM(N, DAG);
10755 break;
10756 case ISD::SDIVREM:
10757 case ISD::UDIVREM:
10758 Res = LowerDivRem(SDValue(N, 0), DAG);
10759 assert(Res.getNumOperands() == 2 && "DivRem needs two values");
10760 Results.push_back(Res.getValue(0));
10761 Results.push_back(Res.getValue(1));
10762 return;
10763 case ISD::SADDSAT:
10764 case ISD::SSUBSAT:
10765 case ISD::UADDSAT:
10766 case ISD::USUBSAT:
10767 Res = LowerADDSUBSAT(SDValue(N, 0), DAG, Subtarget);
10768 break;
10770 ReplaceREADCYCLECOUNTER(N, Results, DAG, Subtarget);
10771 return;
10772 case ISD::UDIV:
10773 case ISD::SDIV:
10774 assert(getTargetMachine().getTargetTriple().isOSWindows() &&
10775 "can only expand DIV on Windows");
10776 return ExpandDIV_Windows(SDValue(N, 0), DAG, N->getOpcode() == ISD::SDIV,
10777 Results);
10780 return;
10782 return ReplaceLongIntrinsic(N, Results, DAG);
10783 case ISD::LOAD:
10784 LowerLOAD(N, Results, DAG);
10785 break;
10786 case ISD::STORE:
10787 Res = LowerAEABIUnalignedStore(SDValue(N, 0), DAG);
10788 break;
10789 case ISD::TRUNCATE:
10790 Res = LowerTruncate(N, DAG, Subtarget);
10791 break;
10792 case ISD::SIGN_EXTEND:
10793 case ISD::ZERO_EXTEND:
10794 Res = LowerVectorExtend(N, DAG, Subtarget);
10795 break;
10798 Res = LowerFP_TO_INT_SAT(SDValue(N, 0), DAG, Subtarget);
10799 break;
10800 }
10801 if (Res.getNode())
10802 Results.push_back(Res);
10803}
10804
10805//===----------------------------------------------------------------------===//
10806// ARM Scheduler Hooks
10807//===----------------------------------------------------------------------===//
10808
10809/// SetupEntryBlockForSjLj - Insert code into the entry block that creates and
10810/// registers the function context.
10811void ARMTargetLowering::SetupEntryBlockForSjLj(MachineInstr &MI,
10813 MachineBasicBlock *DispatchBB,
10814 int FI) const {
10815 assert(!Subtarget->isROPI() && !Subtarget->isRWPI() &&
10816 "ROPI/RWPI not currently supported with SjLj");
10817 const TargetInstrInfo *TII = Subtarget->getInstrInfo();
10818 DebugLoc dl = MI.getDebugLoc();
10819 MachineFunction *MF = MBB->getParent();
10820 MachineRegisterInfo *MRI = &MF->getRegInfo();
10823 const Function &F = MF->getFunction();
10824
10825 bool isThumb = Subtarget->isThumb();
10826 bool isThumb2 = Subtarget->isThumb2();
10827
10828 unsigned PCLabelId = AFI->createPICLabelUId();
10829 unsigned PCAdj = (isThumb || isThumb2) ? 4 : 8;
10831 ARMConstantPoolMBB::Create(F.getContext(), DispatchBB, PCLabelId, PCAdj);
10832 unsigned CPI = MCP->getConstantPoolIndex(CPV, Align(4));
10833
10834 const TargetRegisterClass *TRC = isThumb ? &ARM::tGPRRegClass
10835 : &ARM::GPRRegClass;
10836
10837 // Grab constant pool and fixed stack memory operands.
10838 MachineMemOperand *CPMMO =
10841
10842 MachineMemOperand *FIMMOSt =
10845
10846 // Load the address of the dispatch MBB into the jump buffer.
10847 if (isThumb2) {
10848 // Incoming value: jbuf
10849 // ldr.n r5, LCPI1_1
10850 // orr r5, r5, #1
10851 // add r5, pc
10852 // str r5, [$jbuf, #+4] ; &jbuf[1]
10853 Register NewVReg1 = MRI->createVirtualRegister(TRC);
10854 BuildMI(*MBB, MI, dl, TII->get(ARM::t2LDRpci), NewVReg1)
10856 .addMemOperand(CPMMO)
10858 // Set the low bit because of thumb mode.
10859 Register NewVReg2 = MRI->createVirtualRegister(TRC);
10860 BuildMI(*MBB, MI, dl, TII->get(ARM::t2ORRri), NewVReg2)
10861 .addReg(NewVReg1, RegState::Kill)
10862 .addImm(0x01)
10864 .add(condCodeOp());
10865 Register NewVReg3 = MRI->createVirtualRegister(TRC);
10866 BuildMI(*MBB, MI, dl, TII->get(ARM::tPICADD), NewVReg3)
10867 .addReg(NewVReg2, RegState::Kill)
10868 .addImm(PCLabelId);
10869 BuildMI(*MBB, MI, dl, TII->get(ARM::t2STRi12))
10870 .addReg(NewVReg3, RegState::Kill)
10871 .addFrameIndex(FI)
10872 .addImm(36) // &jbuf[1] :: pc
10873 .addMemOperand(FIMMOSt)
10875 } else if (isThumb) {
10876 // Incoming value: jbuf
10877 // ldr.n r1, LCPI1_4
10878 // add r1, pc
10879 // mov r2, #1
10880 // orrs r1, r2
10881 // add r2, $jbuf, #+4 ; &jbuf[1]
10882 // str r1, [r2]
10883 Register NewVReg1 = MRI->createVirtualRegister(TRC);
10884 BuildMI(*MBB, MI, dl, TII->get(ARM::tLDRpci), NewVReg1)
10886 .addMemOperand(CPMMO)
10888 Register NewVReg2 = MRI->createVirtualRegister(TRC);
10889 BuildMI(*MBB, MI, dl, TII->get(ARM::tPICADD), NewVReg2)
10890 .addReg(NewVReg1, RegState::Kill)
10891 .addImm(PCLabelId);
10892 // Set the low bit because of thumb mode.
10893 Register NewVReg3 = MRI->createVirtualRegister(TRC);
10894 BuildMI(*MBB, MI, dl, TII->get(ARM::tMOVi8), NewVReg3)
10895 .addReg(ARM::CPSR, RegState::Define)
10896 .addImm(1)
10898 Register NewVReg4 = MRI->createVirtualRegister(TRC);
10899 BuildMI(*MBB, MI, dl, TII->get(ARM::tORR), NewVReg4)
10900 .addReg(ARM::CPSR, RegState::Define)
10901 .addReg(NewVReg2, RegState::Kill)
10902 .addReg(NewVReg3, RegState::Kill)
10904 Register NewVReg5 = MRI->createVirtualRegister(TRC);
10905 BuildMI(*MBB, MI, dl, TII->get(ARM::tADDframe), NewVReg5)
10906 .addFrameIndex(FI)
10907 .addImm(36); // &jbuf[1] :: pc
10908 BuildMI(*MBB, MI, dl, TII->get(ARM::tSTRi))
10909 .addReg(NewVReg4, RegState::Kill)
10910 .addReg(NewVReg5, RegState::Kill)
10911 .addImm(0)
10912 .addMemOperand(FIMMOSt)
10914 } else {
10915 // Incoming value: jbuf
10916 // ldr r1, LCPI1_1
10917 // add r1, pc, r1
10918 // str r1, [$jbuf, #+4] ; &jbuf[1]
10919 Register NewVReg1 = MRI->createVirtualRegister(TRC);
10920 BuildMI(*MBB, MI, dl, TII->get(ARM::LDRi12), NewVReg1)
10922 .addImm(0)
10923 .addMemOperand(CPMMO)
10925 Register NewVReg2 = MRI->createVirtualRegister(TRC);
10926 BuildMI(*MBB, MI, dl, TII->get(ARM::PICADD), NewVReg2)
10927 .addReg(NewVReg1, RegState::Kill)
10928 .addImm(PCLabelId)
10930 BuildMI(*MBB, MI, dl, TII->get(ARM::STRi12))
10931 .addReg(NewVReg2, RegState::Kill)
10932 .addFrameIndex(FI)
10933 .addImm(36) // &jbuf[1] :: pc
10934 .addMemOperand(FIMMOSt)
10936 }
10937}
10938
10939void ARMTargetLowering::EmitSjLjDispatchBlock(MachineInstr &MI,
10940 MachineBasicBlock *MBB) const {
10941 const TargetInstrInfo *TII = Subtarget->getInstrInfo();
10942 DebugLoc dl = MI.getDebugLoc();
10943 MachineFunction *MF = MBB->getParent();
10944 MachineRegisterInfo *MRI = &MF->getRegInfo();
10945 MachineFrameInfo &MFI = MF->getFrameInfo();
10946 int FI = MFI.getFunctionContextIndex();
10947
10948 const TargetRegisterClass *TRC = Subtarget->isThumb() ? &ARM::tGPRRegClass
10949 : &ARM::GPRnopcRegClass;
10950
10951 // Get a mapping of the call site numbers to all of the landing pads they're
10952 // associated with.
10953 DenseMap<unsigned, SmallVector<MachineBasicBlock*, 2>> CallSiteNumToLPad;
10954 unsigned MaxCSNum = 0;
10955 for (MachineBasicBlock &BB : *MF) {
10956 if (!BB.isEHPad())
10957 continue;
10958
10959 // FIXME: We should assert that the EH_LABEL is the first MI in the landing
10960 // pad.
10961 for (MachineInstr &II : BB) {
10962 if (!II.isEHLabel())
10963 continue;
10964
10965 MCSymbol *Sym = II.getOperand(0).getMCSymbol();
10966 if (!MF->hasCallSiteLandingPad(Sym)) continue;
10967
10968 SmallVectorImpl<unsigned> &CallSiteIdxs = MF->getCallSiteLandingPad(Sym);
10969 for (unsigned Idx : CallSiteIdxs) {
10970 CallSiteNumToLPad[Idx].push_back(&BB);
10971 MaxCSNum = std::max(MaxCSNum, Idx);
10972 }
10973 break;
10974 }
10975 }
10976
10977 // Get an ordered list of the machine basic blocks for the jump table.
10978 std::vector<MachineBasicBlock*> LPadList;
10979 SmallPtrSet<MachineBasicBlock*, 32> InvokeBBs;
10980 LPadList.reserve(CallSiteNumToLPad.size());
10981 for (unsigned I = 1; I <= MaxCSNum; ++I) {
10982 SmallVectorImpl<MachineBasicBlock*> &MBBList = CallSiteNumToLPad[I];
10983 for (MachineBasicBlock *MBB : MBBList) {
10984 LPadList.push_back(MBB);
10985 InvokeBBs.insert_range(MBB->predecessors());
10986 }
10987 }
10988
10989 assert(!LPadList.empty() &&
10990 "No landing pad destinations for the dispatch jump table!");
10991
10992 // Create the jump table and associated information.
10993 MachineJumpTableInfo *JTI =
10994 MF->getOrCreateJumpTableInfo(MachineJumpTableInfo::EK_Inline);
10995 unsigned MJTI = JTI->createJumpTableIndex(LPadList);
10996
10997 // Create the MBBs for the dispatch code.
10998
10999 // Shove the dispatch's address into the return slot in the function context.
11000 MachineBasicBlock *DispatchBB = MF->CreateMachineBasicBlock();
11001 DispatchBB->setIsEHPad();
11002
11003 MachineBasicBlock *TrapBB = MF->CreateMachineBasicBlock();
11004
11005 BuildMI(TrapBB, dl, TII->get(Subtarget->isThumb() ? ARM::tTRAP : ARM::TRAP));
11006 DispatchBB->addSuccessor(TrapBB);
11007
11008 MachineBasicBlock *DispContBB = MF->CreateMachineBasicBlock();
11009 DispatchBB->addSuccessor(DispContBB);
11010
11011 // Insert and MBBs.
11012 MF->insert(MF->end(), DispatchBB);
11013 MF->insert(MF->end(), DispContBB);
11014 MF->insert(MF->end(), TrapBB);
11015
11016 // Insert code into the entry block that creates and registers the function
11017 // context.
11018 SetupEntryBlockForSjLj(MI, MBB, DispatchBB, FI);
11019
11020 MachineMemOperand *FIMMOLd = MF->getMachineMemOperand(
11023
11024 MachineInstrBuilder MIB;
11025 MIB = BuildMI(DispatchBB, dl, TII->get(ARM::Int_eh_sjlj_dispatchsetup));
11026
11027 const ARMBaseInstrInfo *AII = static_cast<const ARMBaseInstrInfo*>(TII);
11028 const ARMBaseRegisterInfo &RI = AII->getRegisterInfo();
11029
11030 // Add a register mask with no preserved registers. This results in all
11031 // registers being marked as clobbered. This can't work if the dispatch block
11032 // is in a Thumb1 function and is linked with ARM code which uses the FP
11033 // registers, as there is no way to preserve the FP registers in Thumb1 mode.
11035
11036 bool IsPositionIndependent = isPositionIndependent();
11037 unsigned NumLPads = LPadList.size();
11038 if (Subtarget->isThumb2()) {
11039 Register NewVReg1 = MRI->createVirtualRegister(TRC);
11040 BuildMI(DispatchBB, dl, TII->get(ARM::t2LDRi12), NewVReg1)
11041 .addFrameIndex(FI)
11042 .addImm(4)
11043 .addMemOperand(FIMMOLd)
11045
11046 if (NumLPads < 256) {
11047 BuildMI(DispatchBB, dl, TII->get(ARM::t2CMPri))
11048 .addReg(NewVReg1)
11049 .addImm(LPadList.size())
11051 } else {
11052 Register VReg1 = MRI->createVirtualRegister(TRC);
11053 BuildMI(DispatchBB, dl, TII->get(ARM::t2MOVi16), VReg1)
11054 .addImm(NumLPads & 0xFFFF)
11056
11057 unsigned VReg2 = VReg1;
11058 if ((NumLPads & 0xFFFF0000) != 0) {
11059 VReg2 = MRI->createVirtualRegister(TRC);
11060 BuildMI(DispatchBB, dl, TII->get(ARM::t2MOVTi16), VReg2)
11061 .addReg(VReg1)
11062 .addImm(NumLPads >> 16)
11064 }
11065
11066 BuildMI(DispatchBB, dl, TII->get(ARM::t2CMPrr))
11067 .addReg(NewVReg1)
11068 .addReg(VReg2)
11070 }
11071
11072 BuildMI(DispatchBB, dl, TII->get(ARM::t2Bcc))
11073 .addMBB(TrapBB)
11075 .addReg(ARM::CPSR);
11076
11077 Register NewVReg3 = MRI->createVirtualRegister(TRC);
11078 BuildMI(DispContBB, dl, TII->get(ARM::t2LEApcrelJT), NewVReg3)
11079 .addJumpTableIndex(MJTI)
11081
11082 Register NewVReg4 = MRI->createVirtualRegister(TRC);
11083 BuildMI(DispContBB, dl, TII->get(ARM::t2ADDrs), NewVReg4)
11084 .addReg(NewVReg3, RegState::Kill)
11085 .addReg(NewVReg1)
11088 .add(condCodeOp());
11089
11090 BuildMI(DispContBB, dl, TII->get(ARM::t2BR_JT))
11091 .addReg(NewVReg4, RegState::Kill)
11092 .addReg(NewVReg1)
11093 .addJumpTableIndex(MJTI);
11094 } else if (Subtarget->isThumb()) {
11095 Register NewVReg1 = MRI->createVirtualRegister(TRC);
11096 BuildMI(DispatchBB, dl, TII->get(ARM::tLDRspi), NewVReg1)
11097 .addFrameIndex(FI)
11098 .addImm(1)
11099 .addMemOperand(FIMMOLd)
11101
11102 if (NumLPads < 256) {
11103 BuildMI(DispatchBB, dl, TII->get(ARM::tCMPi8))
11104 .addReg(NewVReg1)
11105 .addImm(NumLPads)
11107 } else {
11108 MachineConstantPool *ConstantPool = MF->getConstantPool();
11109 Type *Int32Ty = Type::getInt32Ty(MF->getFunction().getContext());
11110 const Constant *C = ConstantInt::get(Int32Ty, NumLPads);
11111
11112 // MachineConstantPool wants an explicit alignment.
11113 Align Alignment = MF->getDataLayout().getPrefTypeAlign(Int32Ty);
11114 unsigned Idx = ConstantPool->getConstantPoolIndex(C, Alignment);
11115
11116 Register VReg1 = MRI->createVirtualRegister(TRC);
11117 BuildMI(DispatchBB, dl, TII->get(ARM::tLDRpci))
11118 .addReg(VReg1, RegState::Define)
11121 BuildMI(DispatchBB, dl, TII->get(ARM::tCMPr))
11122 .addReg(NewVReg1)
11123 .addReg(VReg1)
11125 }
11126
11127 BuildMI(DispatchBB, dl, TII->get(ARM::tBcc))
11128 .addMBB(TrapBB)
11130 .addReg(ARM::CPSR);
11131
11132 Register NewVReg2 = MRI->createVirtualRegister(TRC);
11133 BuildMI(DispContBB, dl, TII->get(ARM::tLSLri), NewVReg2)
11134 .addReg(ARM::CPSR, RegState::Define)
11135 .addReg(NewVReg1)
11136 .addImm(2)
11138
11139 Register NewVReg3 = MRI->createVirtualRegister(TRC);
11140 BuildMI(DispContBB, dl, TII->get(ARM::tLEApcrelJT), NewVReg3)
11141 .addJumpTableIndex(MJTI)
11143
11144 Register NewVReg4 = MRI->createVirtualRegister(TRC);
11145 BuildMI(DispContBB, dl, TII->get(ARM::tADDrr), NewVReg4)
11146 .addReg(ARM::CPSR, RegState::Define)
11147 .addReg(NewVReg2, RegState::Kill)
11148 .addReg(NewVReg3)
11150
11151 MachineMemOperand *JTMMOLd =
11152 MF->getMachineMemOperand(MachinePointerInfo::getJumpTable(*MF),
11154
11155 Register NewVReg5 = MRI->createVirtualRegister(TRC);
11156 BuildMI(DispContBB, dl, TII->get(ARM::tLDRi), NewVReg5)
11157 .addReg(NewVReg4, RegState::Kill)
11158 .addImm(0)
11159 .addMemOperand(JTMMOLd)
11161
11162 unsigned NewVReg6 = NewVReg5;
11163 if (IsPositionIndependent) {
11164 NewVReg6 = MRI->createVirtualRegister(TRC);
11165 BuildMI(DispContBB, dl, TII->get(ARM::tADDrr), NewVReg6)
11166 .addReg(ARM::CPSR, RegState::Define)
11167 .addReg(NewVReg5, RegState::Kill)
11168 .addReg(NewVReg3)
11170 }
11171
11172 BuildMI(DispContBB, dl, TII->get(ARM::tBR_JTr))
11173 .addReg(NewVReg6, RegState::Kill)
11174 .addJumpTableIndex(MJTI);
11175 } else {
11176 Register NewVReg1 = MRI->createVirtualRegister(TRC);
11177 BuildMI(DispatchBB, dl, TII->get(ARM::LDRi12), NewVReg1)
11178 .addFrameIndex(FI)
11179 .addImm(4)
11180 .addMemOperand(FIMMOLd)
11182
11183 if (NumLPads < 256) {
11184 BuildMI(DispatchBB, dl, TII->get(ARM::CMPri))
11185 .addReg(NewVReg1)
11186 .addImm(NumLPads)
11188 } else if (Subtarget->hasV6T2Ops() && isUInt<16>(NumLPads)) {
11189 Register VReg1 = MRI->createVirtualRegister(TRC);
11190 BuildMI(DispatchBB, dl, TII->get(ARM::MOVi16), VReg1)
11191 .addImm(NumLPads & 0xFFFF)
11193
11194 unsigned VReg2 = VReg1;
11195 if ((NumLPads & 0xFFFF0000) != 0) {
11196 VReg2 = MRI->createVirtualRegister(TRC);
11197 BuildMI(DispatchBB, dl, TII->get(ARM::MOVTi16), VReg2)
11198 .addReg(VReg1)
11199 .addImm(NumLPads >> 16)
11201 }
11202
11203 BuildMI(DispatchBB, dl, TII->get(ARM::CMPrr))
11204 .addReg(NewVReg1)
11205 .addReg(VReg2)
11207 } else {
11208 MachineConstantPool *ConstantPool = MF->getConstantPool();
11209 Type *Int32Ty = Type::getInt32Ty(MF->getFunction().getContext());
11210 const Constant *C = ConstantInt::get(Int32Ty, NumLPads);
11211
11212 // MachineConstantPool wants an explicit alignment.
11213 Align Alignment = MF->getDataLayout().getPrefTypeAlign(Int32Ty);
11214 unsigned Idx = ConstantPool->getConstantPoolIndex(C, Alignment);
11215
11216 Register VReg1 = MRI->createVirtualRegister(TRC);
11217 BuildMI(DispatchBB, dl, TII->get(ARM::LDRcp))
11218 .addReg(VReg1, RegState::Define)
11220 .addImm(0)
11222 BuildMI(DispatchBB, dl, TII->get(ARM::CMPrr))
11223 .addReg(NewVReg1)
11224 .addReg(VReg1, RegState::Kill)
11226 }
11227
11228 BuildMI(DispatchBB, dl, TII->get(ARM::Bcc))
11229 .addMBB(TrapBB)
11231 .addReg(ARM::CPSR);
11232
11233 Register NewVReg3 = MRI->createVirtualRegister(TRC);
11234 BuildMI(DispContBB, dl, TII->get(ARM::MOVsi), NewVReg3)
11235 .addReg(NewVReg1)
11238 .add(condCodeOp());
11239 Register NewVReg4 = MRI->createVirtualRegister(TRC);
11240 BuildMI(DispContBB, dl, TII->get(ARM::LEApcrelJT), NewVReg4)
11241 .addJumpTableIndex(MJTI)
11243
11244 MachineMemOperand *JTMMOLd =
11245 MF->getMachineMemOperand(MachinePointerInfo::getJumpTable(*MF),
11247 Register NewVReg5 = MRI->createVirtualRegister(TRC);
11248 BuildMI(DispContBB, dl, TII->get(ARM::LDRrs), NewVReg5)
11249 .addReg(NewVReg3, RegState::Kill)
11250 .addReg(NewVReg4)
11251 .addImm(0)
11252 .addMemOperand(JTMMOLd)
11254
11255 if (IsPositionIndependent) {
11256 BuildMI(DispContBB, dl, TII->get(ARM::BR_JTadd))
11257 .addReg(NewVReg5, RegState::Kill)
11258 .addReg(NewVReg4)
11259 .addJumpTableIndex(MJTI);
11260 } else {
11261 BuildMI(DispContBB, dl, TII->get(ARM::BR_JTr))
11262 .addReg(NewVReg5, RegState::Kill)
11263 .addJumpTableIndex(MJTI);
11264 }
11265 }
11266
11267 // Add the jump table entries as successors to the MBB.
11268 SmallPtrSet<MachineBasicBlock*, 8> SeenMBBs;
11269 for (MachineBasicBlock *CurMBB : LPadList) {
11270 if (SeenMBBs.insert(CurMBB).second)
11271 DispContBB->addSuccessor(CurMBB);
11272 }
11273
11274 // N.B. the order the invoke BBs are processed in doesn't matter here.
11275 const MCPhysReg *SavedRegs = RI.getCalleeSavedRegs(MF);
11277 for (MachineBasicBlock *BB : InvokeBBs) {
11278
11279 // Remove the landing pad successor from the invoke block and replace it
11280 // with the new dispatch block.
11281 SmallVector<MachineBasicBlock*, 4> Successors(BB->successors());
11282 while (!Successors.empty()) {
11283 MachineBasicBlock *SMBB = Successors.pop_back_val();
11284 if (SMBB->isEHPad()) {
11285 BB->removeSuccessor(SMBB);
11286 MBBLPads.push_back(SMBB);
11287 }
11288 }
11289
11290 BB->addSuccessor(DispatchBB, BranchProbability::getZero());
11291 BB->normalizeSuccProbs();
11292
11293 // Find the invoke call and mark all of the callee-saved registers as
11294 // 'implicit defined' so that they're spilled. This prevents code from
11295 // moving instructions to before the EH block, where they will never be
11296 // executed.
11298 II = BB->rbegin(), IE = BB->rend(); II != IE; ++II) {
11299 if (!II->isCall()) continue;
11300
11301 DenseSet<unsigned> DefRegs;
11303 OI = II->operands_begin(), OE = II->operands_end();
11304 OI != OE; ++OI) {
11305 if (!OI->isReg()) continue;
11306 DefRegs.insert(OI->getReg());
11307 }
11308
11309 MachineInstrBuilder MIB(*MF, &*II);
11310
11311 for (unsigned i = 0; SavedRegs[i] != 0; ++i) {
11312 unsigned Reg = SavedRegs[i];
11313 if (Subtarget->isThumb2() &&
11314 !ARM::tGPRRegClass.contains(Reg) &&
11315 !ARM::hGPRRegClass.contains(Reg))
11316 continue;
11317 if (Subtarget->isThumb1Only() && !ARM::tGPRRegClass.contains(Reg))
11318 continue;
11319 if (!Subtarget->isThumb() && !ARM::GPRRegClass.contains(Reg))
11320 continue;
11321 if (!DefRegs.contains(Reg))
11323 }
11324
11325 break;
11326 }
11327 }
11328
11329 // Mark all former landing pads as non-landing pads. The dispatch is the only
11330 // landing pad now.
11331 for (MachineBasicBlock *MBBLPad : MBBLPads)
11332 MBBLPad->setIsEHPad(false);
11333
11334 // The instruction is gone now.
11335 MI.eraseFromParent();
11336}
11337
11338static
11340 for (MachineBasicBlock *S : MBB->successors())
11341 if (S != Succ)
11342 return S;
11343 llvm_unreachable("Expecting a BB with two successors!");
11344}
11345
11346/// Return the load opcode for a given load size. If load size >= 8,
11347/// neon opcode will be returned.
11348static unsigned getLdOpcode(unsigned LdSize, bool IsThumb1, bool IsThumb2) {
11349 if (LdSize >= 8)
11350 return LdSize == 16 ? ARM::VLD1q32wb_fixed
11351 : LdSize == 8 ? ARM::VLD1d32wb_fixed : 0;
11352 if (IsThumb1)
11353 return LdSize == 4 ? ARM::tLDRi
11354 : LdSize == 2 ? ARM::tLDRHi
11355 : LdSize == 1 ? ARM::tLDRBi : 0;
11356 if (IsThumb2)
11357 return LdSize == 4 ? ARM::t2LDR_POST
11358 : LdSize == 2 ? ARM::t2LDRH_POST
11359 : LdSize == 1 ? ARM::t2LDRB_POST : 0;
11360 return LdSize == 4 ? ARM::LDR_POST_IMM
11361 : LdSize == 2 ? ARM::LDRH_POST
11362 : LdSize == 1 ? ARM::LDRB_POST_IMM : 0;
11363}
11364
11365/// Return the store opcode for a given store size. If store size >= 8,
11366/// neon opcode will be returned.
11367static unsigned getStOpcode(unsigned StSize, bool IsThumb1, bool IsThumb2) {
11368 if (StSize >= 8)
11369 return StSize == 16 ? ARM::VST1q32wb_fixed
11370 : StSize == 8 ? ARM::VST1d32wb_fixed : 0;
11371 if (IsThumb1)
11372 return StSize == 4 ? ARM::tSTRi
11373 : StSize == 2 ? ARM::tSTRHi
11374 : StSize == 1 ? ARM::tSTRBi : 0;
11375 if (IsThumb2)
11376 return StSize == 4 ? ARM::t2STR_POST
11377 : StSize == 2 ? ARM::t2STRH_POST
11378 : StSize == 1 ? ARM::t2STRB_POST : 0;
11379 return StSize == 4 ? ARM::STR_POST_IMM
11380 : StSize == 2 ? ARM::STRH_POST
11381 : StSize == 1 ? ARM::STRB_POST_IMM : 0;
11382}
11383
11384/// Emit a post-increment load operation with given size. The instructions
11385/// will be added to BB at Pos.
11387 const TargetInstrInfo *TII, const DebugLoc &dl,
11388 unsigned LdSize, unsigned Data, unsigned AddrIn,
11389 unsigned AddrOut, bool IsThumb1, bool IsThumb2) {
11390 unsigned LdOpc = getLdOpcode(LdSize, IsThumb1, IsThumb2);
11391 assert(LdOpc != 0 && "Should have a load opcode");
11392 if (LdSize >= 8) {
11393 BuildMI(*BB, Pos, dl, TII->get(LdOpc), Data)
11394 .addReg(AddrOut, RegState::Define)
11395 .addReg(AddrIn)
11396 .addImm(0)
11398 } else if (IsThumb1) {
11399 // load + update AddrIn
11400 BuildMI(*BB, Pos, dl, TII->get(LdOpc), Data)
11401 .addReg(AddrIn)
11402 .addImm(0)
11404 BuildMI(*BB, Pos, dl, TII->get(ARM::tADDi8), AddrOut)
11405 .add(t1CondCodeOp())
11406 .addReg(AddrIn)
11407 .addImm(LdSize)
11409 } else if (IsThumb2) {
11410 BuildMI(*BB, Pos, dl, TII->get(LdOpc), Data)
11411 .addReg(AddrOut, RegState::Define)
11412 .addReg(AddrIn)
11413 .addImm(LdSize)
11415 } else { // arm
11416 BuildMI(*BB, Pos, dl, TII->get(LdOpc), Data)
11417 .addReg(AddrOut, RegState::Define)
11418 .addReg(AddrIn)
11419 .addReg(0)
11420 .addImm(LdSize)
11422 }
11423}
11424
11425/// Emit a post-increment store operation with given size. The instructions
11426/// will be added to BB at Pos.
11428 const TargetInstrInfo *TII, const DebugLoc &dl,
11429 unsigned StSize, unsigned Data, unsigned AddrIn,
11430 unsigned AddrOut, bool IsThumb1, bool IsThumb2) {
11431 unsigned StOpc = getStOpcode(StSize, IsThumb1, IsThumb2);
11432 assert(StOpc != 0 && "Should have a store opcode");
11433 if (StSize >= 8) {
11434 BuildMI(*BB, Pos, dl, TII->get(StOpc), AddrOut)
11435 .addReg(AddrIn)
11436 .addImm(0)
11437 .addReg(Data)
11439 } else if (IsThumb1) {
11440 // store + update AddrIn
11441 BuildMI(*BB, Pos, dl, TII->get(StOpc))
11442 .addReg(Data)
11443 .addReg(AddrIn)
11444 .addImm(0)
11446 BuildMI(*BB, Pos, dl, TII->get(ARM::tADDi8), AddrOut)
11447 .add(t1CondCodeOp())
11448 .addReg(AddrIn)
11449 .addImm(StSize)
11451 } else if (IsThumb2) {
11452 BuildMI(*BB, Pos, dl, TII->get(StOpc), AddrOut)
11453 .addReg(Data)
11454 .addReg(AddrIn)
11455 .addImm(StSize)
11457 } else { // arm
11458 BuildMI(*BB, Pos, dl, TII->get(StOpc), AddrOut)
11459 .addReg(Data)
11460 .addReg(AddrIn)
11461 .addReg(0)
11462 .addImm(StSize)
11464 }
11465}
11466
11468ARMTargetLowering::EmitStructByval(MachineInstr &MI,
11469 MachineBasicBlock *BB) const {
11470 // This pseudo instruction has 3 operands: dst, src, size
11471 // We expand it to a loop if size > Subtarget->getMaxInlineSizeThreshold().
11472 // Otherwise, we will generate unrolled scalar copies.
11473 const TargetInstrInfo *TII = Subtarget->getInstrInfo();
11474 const BasicBlock *LLVM_BB = BB->getBasicBlock();
11476
11477 Register dest = MI.getOperand(0).getReg();
11478 Register src = MI.getOperand(1).getReg();
11479 unsigned SizeVal = MI.getOperand(2).getImm();
11480 unsigned Alignment = MI.getOperand(3).getImm();
11481 DebugLoc dl = MI.getDebugLoc();
11482
11483 MachineFunction *MF = BB->getParent();
11484 MachineRegisterInfo &MRI = MF->getRegInfo();
11485 unsigned UnitSize = 0;
11486 const TargetRegisterClass *TRC = nullptr;
11487 const TargetRegisterClass *VecTRC = nullptr;
11488
11489 bool IsThumb1 = Subtarget->isThumb1Only();
11490 bool IsThumb2 = Subtarget->isThumb2();
11491 bool IsThumb = Subtarget->isThumb();
11492
11493 if (Alignment & 1) {
11494 UnitSize = 1;
11495 } else if (Alignment & 2) {
11496 UnitSize = 2;
11497 } else {
11498 // Check whether we can use NEON instructions.
11499 if (!MF->getFunction().hasFnAttribute(Attribute::NoImplicitFloat) &&
11500 Subtarget->hasNEON()) {
11501 if ((Alignment % 16 == 0) && SizeVal >= 16)
11502 UnitSize = 16;
11503 else if ((Alignment % 8 == 0) && SizeVal >= 8)
11504 UnitSize = 8;
11505 }
11506 // Can't use NEON instructions.
11507 if (UnitSize == 0)
11508 UnitSize = 4;
11509 }
11510
11511 // Select the correct opcode and register class for unit size load/store
11512 bool IsNeon = UnitSize >= 8;
11513 TRC = IsThumb ? &ARM::tGPRRegClass : &ARM::GPRRegClass;
11514 if (IsNeon)
11515 VecTRC = UnitSize == 16 ? &ARM::DPairRegClass
11516 : UnitSize == 8 ? &ARM::DPRRegClass
11517 : nullptr;
11518
11519 unsigned BytesLeft = SizeVal % UnitSize;
11520 unsigned LoopSize = SizeVal - BytesLeft;
11521
11522 if (SizeVal <= Subtarget->getMaxInlineSizeThreshold()) {
11523 // Use LDR and STR to copy.
11524 // [scratch, srcOut] = LDR_POST(srcIn, UnitSize)
11525 // [destOut] = STR_POST(scratch, destIn, UnitSize)
11526 unsigned srcIn = src;
11527 unsigned destIn = dest;
11528 for (unsigned i = 0; i < LoopSize; i+=UnitSize) {
11529 Register srcOut = MRI.createVirtualRegister(TRC);
11530 Register destOut = MRI.createVirtualRegister(TRC);
11531 Register scratch = MRI.createVirtualRegister(IsNeon ? VecTRC : TRC);
11532 emitPostLd(BB, MI, TII, dl, UnitSize, scratch, srcIn, srcOut,
11533 IsThumb1, IsThumb2);
11534 emitPostSt(BB, MI, TII, dl, UnitSize, scratch, destIn, destOut,
11535 IsThumb1, IsThumb2);
11536 srcIn = srcOut;
11537 destIn = destOut;
11538 }
11539
11540 // Handle the leftover bytes with LDRB and STRB.
11541 // [scratch, srcOut] = LDRB_POST(srcIn, 1)
11542 // [destOut] = STRB_POST(scratch, destIn, 1)
11543 for (unsigned i = 0; i < BytesLeft; i++) {
11544 Register srcOut = MRI.createVirtualRegister(TRC);
11545 Register destOut = MRI.createVirtualRegister(TRC);
11546 Register scratch = MRI.createVirtualRegister(TRC);
11547 emitPostLd(BB, MI, TII, dl, 1, scratch, srcIn, srcOut,
11548 IsThumb1, IsThumb2);
11549 emitPostSt(BB, MI, TII, dl, 1, scratch, destIn, destOut,
11550 IsThumb1, IsThumb2);
11551 srcIn = srcOut;
11552 destIn = destOut;
11553 }
11554 MI.eraseFromParent(); // The instruction is gone now.
11555 return BB;
11556 }
11557
11558 // Expand the pseudo op to a loop.
11559 // thisMBB:
11560 // ...
11561 // movw varEnd, # --> with thumb2
11562 // movt varEnd, #
11563 // ldrcp varEnd, idx --> without thumb2
11564 // fallthrough --> loopMBB
11565 // loopMBB:
11566 // PHI varPhi, varEnd, varLoop
11567 // PHI srcPhi, src, srcLoop
11568 // PHI destPhi, dst, destLoop
11569 // [scratch, srcLoop] = LDR_POST(srcPhi, UnitSize)
11570 // [destLoop] = STR_POST(scratch, destPhi, UnitSize)
11571 // subs varLoop, varPhi, #UnitSize
11572 // bne loopMBB
11573 // fallthrough --> exitMBB
11574 // exitMBB:
11575 // epilogue to handle left-over bytes
11576 // [scratch, srcOut] = LDRB_POST(srcLoop, 1)
11577 // [destOut] = STRB_POST(scratch, destLoop, 1)
11578 MachineBasicBlock *loopMBB = MF->CreateMachineBasicBlock(LLVM_BB);
11579 MachineBasicBlock *exitMBB = MF->CreateMachineBasicBlock(LLVM_BB);
11580 MF->insert(It, loopMBB);
11581 MF->insert(It, exitMBB);
11582
11583 // Set the call frame size on entry to the new basic blocks.
11584 unsigned CallFrameSize = TII->getCallFrameSizeAt(MI);
11585 loopMBB->setCallFrameSize(CallFrameSize);
11586 exitMBB->setCallFrameSize(CallFrameSize);
11587
11588 // Transfer the remainder of BB and its successor edges to exitMBB.
11589 exitMBB->splice(exitMBB->begin(), BB,
11590 std::next(MachineBasicBlock::iterator(MI)), BB->end());
11592
11593 // Load an immediate to varEnd.
11594 Register varEnd = MRI.createVirtualRegister(TRC);
11595 if (Subtarget->useMovt()) {
11596 BuildMI(BB, dl, TII->get(IsThumb ? ARM::t2MOVi32imm : ARM::MOVi32imm),
11597 varEnd)
11598 .addImm(LoopSize);
11599 } else if (Subtarget->genExecuteOnly()) {
11600 assert(IsThumb && "Non-thumb expected to have used movt");
11601 BuildMI(BB, dl, TII->get(ARM::tMOVi32imm), varEnd).addImm(LoopSize);
11602 } else {
11603 MachineConstantPool *ConstantPool = MF->getConstantPool();
11604 Type *Int32Ty = Type::getInt32Ty(MF->getFunction().getContext());
11605 const Constant *C = ConstantInt::get(Int32Ty, LoopSize);
11606
11607 // MachineConstantPool wants an explicit alignment.
11609 unsigned Idx = ConstantPool->getConstantPoolIndex(C, Alignment);
11610 MachineMemOperand *CPMMO =
11613
11614 if (IsThumb)
11615 BuildMI(*BB, MI, dl, TII->get(ARM::tLDRpci))
11616 .addReg(varEnd, RegState::Define)
11619 .addMemOperand(CPMMO);
11620 else
11621 BuildMI(*BB, MI, dl, TII->get(ARM::LDRcp))
11622 .addReg(varEnd, RegState::Define)
11624 .addImm(0)
11626 .addMemOperand(CPMMO);
11627 }
11628 BB->addSuccessor(loopMBB);
11629
11630 // Generate the loop body:
11631 // varPhi = PHI(varLoop, varEnd)
11632 // srcPhi = PHI(srcLoop, src)
11633 // destPhi = PHI(destLoop, dst)
11634 MachineBasicBlock *entryBB = BB;
11635 BB = loopMBB;
11636 Register varLoop = MRI.createVirtualRegister(TRC);
11637 Register varPhi = MRI.createVirtualRegister(TRC);
11638 Register srcLoop = MRI.createVirtualRegister(TRC);
11639 Register srcPhi = MRI.createVirtualRegister(TRC);
11640 Register destLoop = MRI.createVirtualRegister(TRC);
11641 Register destPhi = MRI.createVirtualRegister(TRC);
11642
11643 BuildMI(*BB, BB->begin(), dl, TII->get(ARM::PHI), varPhi)
11644 .addReg(varLoop).addMBB(loopMBB)
11645 .addReg(varEnd).addMBB(entryBB);
11646 BuildMI(BB, dl, TII->get(ARM::PHI), srcPhi)
11647 .addReg(srcLoop).addMBB(loopMBB)
11648 .addReg(src).addMBB(entryBB);
11649 BuildMI(BB, dl, TII->get(ARM::PHI), destPhi)
11650 .addReg(destLoop).addMBB(loopMBB)
11651 .addReg(dest).addMBB(entryBB);
11652
11653 // [scratch, srcLoop] = LDR_POST(srcPhi, UnitSize)
11654 // [destLoop] = STR_POST(scratch, destPhi, UnitSiz)
11655 Register scratch = MRI.createVirtualRegister(IsNeon ? VecTRC : TRC);
11656 emitPostLd(BB, BB->end(), TII, dl, UnitSize, scratch, srcPhi, srcLoop,
11657 IsThumb1, IsThumb2);
11658 emitPostSt(BB, BB->end(), TII, dl, UnitSize, scratch, destPhi, destLoop,
11659 IsThumb1, IsThumb2);
11660
11661 // Decrement loop variable by UnitSize.
11662 if (IsThumb1) {
11663 BuildMI(*BB, BB->end(), dl, TII->get(ARM::tSUBi8), varLoop)
11664 .add(t1CondCodeOp())
11665 .addReg(varPhi)
11666 .addImm(UnitSize)
11668 } else {
11669 MachineInstrBuilder MIB =
11670 BuildMI(*BB, BB->end(), dl,
11671 TII->get(IsThumb2 ? ARM::t2SUBri : ARM::SUBri), varLoop);
11672 MIB.addReg(varPhi)
11673 .addImm(UnitSize)
11675 .add(condCodeOp());
11676 MIB->getOperand(5).setReg(ARM::CPSR);
11677 MIB->getOperand(5).setIsDef(true);
11678 }
11679 BuildMI(*BB, BB->end(), dl,
11680 TII->get(IsThumb1 ? ARM::tBcc : IsThumb2 ? ARM::t2Bcc : ARM::Bcc))
11681 .addMBB(loopMBB).addImm(ARMCC::NE).addReg(ARM::CPSR);
11682
11683 // loopMBB can loop back to loopMBB or fall through to exitMBB.
11684 BB->addSuccessor(loopMBB);
11685 BB->addSuccessor(exitMBB);
11686
11687 // Add epilogue to handle BytesLeft.
11688 BB = exitMBB;
11689 auto StartOfExit = exitMBB->begin();
11690
11691 // [scratch, srcOut] = LDRB_POST(srcLoop, 1)
11692 // [destOut] = STRB_POST(scratch, destLoop, 1)
11693 unsigned srcIn = srcLoop;
11694 unsigned destIn = destLoop;
11695 for (unsigned i = 0; i < BytesLeft; i++) {
11696 Register srcOut = MRI.createVirtualRegister(TRC);
11697 Register destOut = MRI.createVirtualRegister(TRC);
11698 Register scratch = MRI.createVirtualRegister(TRC);
11699 emitPostLd(BB, StartOfExit, TII, dl, 1, scratch, srcIn, srcOut,
11700 IsThumb1, IsThumb2);
11701 emitPostSt(BB, StartOfExit, TII, dl, 1, scratch, destIn, destOut,
11702 IsThumb1, IsThumb2);
11703 srcIn = srcOut;
11704 destIn = destOut;
11705 }
11706
11707 MI.eraseFromParent(); // The instruction is gone now.
11708 return BB;
11709}
11710
11712ARMTargetLowering::EmitLowered__chkstk(MachineInstr &MI,
11713 MachineBasicBlock *MBB) const {
11714 const TargetMachine &TM = getTargetMachine();
11715 const TargetInstrInfo &TII = *Subtarget->getInstrInfo();
11716 DebugLoc DL = MI.getDebugLoc();
11717
11718 assert(TM.getTargetTriple().isOSWindows() &&
11719 "__chkstk is only supported on Windows");
11720 assert(Subtarget->isThumb2() && "Windows on ARM requires Thumb-2 mode");
11721
11722 // __chkstk takes the number of words to allocate on the stack in R4, and
11723 // returns the stack adjustment in number of bytes in R4. This will not
11724 // clober any other registers (other than the obvious lr).
11725 //
11726 // Although, technically, IP should be considered a register which may be
11727 // clobbered, the call itself will not touch it. Windows on ARM is a pure
11728 // thumb-2 environment, so there is no interworking required. As a result, we
11729 // do not expect a veneer to be emitted by the linker, clobbering IP.
11730 //
11731 // Each module receives its own copy of __chkstk, so no import thunk is
11732 // required, again, ensuring that IP is not clobbered.
11733 //
11734 // Finally, although some linkers may theoretically provide a trampoline for
11735 // out of range calls (which is quite common due to a 32M range limitation of
11736 // branches for Thumb), we can generate the long-call version via
11737 // -mcmodel=large, alleviating the need for the trampoline which may clobber
11738 // IP.
11739
11740 RTLIB::LibcallImpl ChkStkLibcall = getLibcallImpl(RTLIB::STACK_PROBE);
11741 if (ChkStkLibcall == RTLIB::Unsupported)
11742 reportFatalUsageError("no available implementation of __chkstk");
11743
11744 const char *ChkStk = getLibcallImplName(ChkStkLibcall).data();
11745 switch (TM.getCodeModel()) {
11746 case CodeModel::Tiny:
11747 llvm_unreachable("Tiny code model not available on ARM.");
11748 case CodeModel::Small:
11749 case CodeModel::Medium:
11750 case CodeModel::Kernel:
11751 BuildMI(*MBB, MI, DL, TII.get(ARM::tBL))
11753 .addExternalSymbol(ChkStk)
11756 .addReg(ARM::R12,
11758 .addReg(ARM::CPSR,
11760 break;
11761 case CodeModel::Large: {
11762 MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo();
11763 Register Reg = MRI.createVirtualRegister(&ARM::rGPRRegClass);
11764
11765 BuildMI(*MBB, MI, DL, TII.get(ARM::t2MOVi32imm), Reg)
11766 .addExternalSymbol(ChkStk);
11772 .addReg(ARM::R12,
11774 .addReg(ARM::CPSR,
11776 break;
11777 }
11778 }
11779
11780 BuildMI(*MBB, MI, DL, TII.get(ARM::t2SUBrr), ARM::SP)
11781 .addReg(ARM::SP, RegState::Kill)
11782 .addReg(ARM::R4, RegState::Kill)
11785 .add(condCodeOp());
11786
11787 MI.eraseFromParent();
11788 return MBB;
11789}
11790
11792ARMTargetLowering::EmitLowered__dbzchk(MachineInstr &MI,
11793 MachineBasicBlock *MBB) const {
11794 DebugLoc DL = MI.getDebugLoc();
11795 MachineFunction *MF = MBB->getParent();
11796 const TargetInstrInfo *TII = Subtarget->getInstrInfo();
11797
11798 MachineBasicBlock *ContBB = MF->CreateMachineBasicBlock();
11799 MF->insert(++MBB->getIterator(), ContBB);
11800 ContBB->splice(ContBB->begin(), MBB,
11801 std::next(MachineBasicBlock::iterator(MI)), MBB->end());
11803 MBB->addSuccessor(ContBB);
11804
11805 MachineBasicBlock *TrapBB = MF->CreateMachineBasicBlock();
11806 BuildMI(TrapBB, DL, TII->get(ARM::t__brkdiv0));
11807 MF->push_back(TrapBB);
11808 MBB->addSuccessor(TrapBB);
11809
11810 BuildMI(*MBB, MI, DL, TII->get(ARM::tCMPi8))
11811 .addReg(MI.getOperand(0).getReg())
11812 .addImm(0)
11814 BuildMI(*MBB, MI, DL, TII->get(ARM::t2Bcc))
11815 .addMBB(TrapBB)
11817 .addReg(ARM::CPSR);
11818
11819 MI.eraseFromParent();
11820 return ContBB;
11821}
11822
11823// The CPSR operand of SelectItr might be missing a kill marker
11824// because there were multiple uses of CPSR, and ISel didn't know
11825// which to mark. Figure out whether SelectItr should have had a
11826// kill marker, and set it if it should. Returns the correct kill
11827// marker value.
11830 const TargetRegisterInfo* TRI) {
11831 // Scan forward through BB for a use/def of CPSR.
11832 MachineBasicBlock::iterator miI(std::next(SelectItr));
11833 for (MachineBasicBlock::iterator miE = BB->end(); miI != miE; ++miI) {
11834 const MachineInstr& mi = *miI;
11835 if (mi.readsRegister(ARM::CPSR, /*TRI=*/nullptr))
11836 return false;
11837 if (mi.definesRegister(ARM::CPSR, /*TRI=*/nullptr))
11838 break; // Should have kill-flag - update below.
11839 }
11840
11841 // If we hit the end of the block, check whether CPSR is live into a
11842 // successor.
11843 if (miI == BB->end()) {
11844 for (MachineBasicBlock *Succ : BB->successors())
11845 if (Succ->isLiveIn(ARM::CPSR))
11846 return false;
11847 }
11848
11849 // We found a def, or hit the end of the basic block and CPSR wasn't live
11850 // out. SelectMI should have a kill flag on CPSR.
11851 SelectItr->addRegisterKilled(ARM::CPSR, TRI);
11852 return true;
11853}
11854
11855/// Adds logic in loop entry MBB to calculate loop iteration count and adds
11856/// t2WhileLoopSetup and t2WhileLoopStart to generate WLS loop
11858 MachineBasicBlock *TpLoopBody,
11859 MachineBasicBlock *TpExit, Register OpSizeReg,
11860 const TargetInstrInfo *TII, DebugLoc Dl,
11861 MachineRegisterInfo &MRI) {
11862 // Calculates loop iteration count = ceil(n/16) = (n + 15) >> 4.
11863 Register AddDestReg = MRI.createVirtualRegister(&ARM::rGPRRegClass);
11864 BuildMI(TpEntry, Dl, TII->get(ARM::t2ADDri), AddDestReg)
11865 .addUse(OpSizeReg)
11866 .addImm(15)
11868 .addReg(0);
11869
11870 Register LsrDestReg = MRI.createVirtualRegister(&ARM::rGPRRegClass);
11871 BuildMI(TpEntry, Dl, TII->get(ARM::t2LSRri), LsrDestReg)
11872 .addUse(AddDestReg, RegState::Kill)
11873 .addImm(4)
11875 .addReg(0);
11876
11877 Register TotalIterationsReg = MRI.createVirtualRegister(&ARM::GPRlrRegClass);
11878 BuildMI(TpEntry, Dl, TII->get(ARM::t2WhileLoopSetup), TotalIterationsReg)
11879 .addUse(LsrDestReg, RegState::Kill);
11880
11881 BuildMI(TpEntry, Dl, TII->get(ARM::t2WhileLoopStart))
11882 .addUse(TotalIterationsReg)
11883 .addMBB(TpExit);
11884
11885 BuildMI(TpEntry, Dl, TII->get(ARM::t2B))
11886 .addMBB(TpLoopBody)
11888
11889 return TotalIterationsReg;
11890}
11891
11892/// Adds logic in the loopBody MBB to generate MVE_VCTP, t2DoLoopDec and
11893/// t2DoLoopEnd. These are used by later passes to generate tail predicated
11894/// loops.
11895static void genTPLoopBody(MachineBasicBlock *TpLoopBody,
11896 MachineBasicBlock *TpEntry, MachineBasicBlock *TpExit,
11897 const TargetInstrInfo *TII, DebugLoc Dl,
11898 MachineRegisterInfo &MRI, Register OpSrcReg,
11899 Register OpDestReg, Register ElementCountReg,
11900 Register TotalIterationsReg, bool IsMemcpy) {
11901 // First insert 4 PHI nodes for: Current pointer to Src (if memcpy), Dest
11902 // array, loop iteration counter, predication counter.
11903
11904 Register SrcPhiReg, CurrSrcReg;
11905 if (IsMemcpy) {
11906 // Current position in the src array
11907 SrcPhiReg = MRI.createVirtualRegister(&ARM::rGPRRegClass);
11908 CurrSrcReg = MRI.createVirtualRegister(&ARM::rGPRRegClass);
11909 BuildMI(TpLoopBody, Dl, TII->get(ARM::PHI), SrcPhiReg)
11910 .addUse(OpSrcReg)
11911 .addMBB(TpEntry)
11912 .addUse(CurrSrcReg)
11913 .addMBB(TpLoopBody);
11914 }
11915
11916 // Current position in the dest array
11917 Register DestPhiReg = MRI.createVirtualRegister(&ARM::rGPRRegClass);
11918 Register CurrDestReg = MRI.createVirtualRegister(&ARM::rGPRRegClass);
11919 BuildMI(TpLoopBody, Dl, TII->get(ARM::PHI), DestPhiReg)
11920 .addUse(OpDestReg)
11921 .addMBB(TpEntry)
11922 .addUse(CurrDestReg)
11923 .addMBB(TpLoopBody);
11924
11925 // Current loop counter
11926 Register LoopCounterPhiReg = MRI.createVirtualRegister(&ARM::GPRlrRegClass);
11927 Register RemainingLoopIterationsReg =
11928 MRI.createVirtualRegister(&ARM::GPRlrRegClass);
11929 BuildMI(TpLoopBody, Dl, TII->get(ARM::PHI), LoopCounterPhiReg)
11930 .addUse(TotalIterationsReg)
11931 .addMBB(TpEntry)
11932 .addUse(RemainingLoopIterationsReg)
11933 .addMBB(TpLoopBody);
11934
11935 // Predication counter
11936 Register PredCounterPhiReg = MRI.createVirtualRegister(&ARM::rGPRRegClass);
11937 Register RemainingElementsReg = MRI.createVirtualRegister(&ARM::rGPRRegClass);
11938 BuildMI(TpLoopBody, Dl, TII->get(ARM::PHI), PredCounterPhiReg)
11939 .addUse(ElementCountReg)
11940 .addMBB(TpEntry)
11941 .addUse(RemainingElementsReg)
11942 .addMBB(TpLoopBody);
11943
11944 // Pass predication counter to VCTP
11945 Register VccrReg = MRI.createVirtualRegister(&ARM::VCCRRegClass);
11946 BuildMI(TpLoopBody, Dl, TII->get(ARM::MVE_VCTP8), VccrReg)
11947 .addUse(PredCounterPhiReg)
11949 .addReg(0)
11950 .addReg(0);
11951
11952 BuildMI(TpLoopBody, Dl, TII->get(ARM::t2SUBri), RemainingElementsReg)
11953 .addUse(PredCounterPhiReg)
11954 .addImm(16)
11956 .addReg(0);
11957
11958 // VLDRB (only if memcpy) and VSTRB instructions, predicated using VPR
11959 Register SrcValueReg;
11960 if (IsMemcpy) {
11961 SrcValueReg = MRI.createVirtualRegister(&ARM::MQPRRegClass);
11962 BuildMI(TpLoopBody, Dl, TII->get(ARM::MVE_VLDRBU8_post))
11963 .addDef(CurrSrcReg)
11964 .addDef(SrcValueReg)
11965 .addReg(SrcPhiReg)
11966 .addImm(16)
11968 .addUse(VccrReg)
11969 .addReg(0);
11970 } else
11971 SrcValueReg = OpSrcReg;
11972
11973 BuildMI(TpLoopBody, Dl, TII->get(ARM::MVE_VSTRBU8_post))
11974 .addDef(CurrDestReg)
11975 .addUse(SrcValueReg)
11976 .addReg(DestPhiReg)
11977 .addImm(16)
11979 .addUse(VccrReg)
11980 .addReg(0);
11981
11982 // Add the pseudoInstrs for decrementing the loop counter and marking the
11983 // end:t2DoLoopDec and t2DoLoopEnd
11984 BuildMI(TpLoopBody, Dl, TII->get(ARM::t2LoopDec), RemainingLoopIterationsReg)
11985 .addUse(LoopCounterPhiReg)
11986 .addImm(1);
11987
11988 BuildMI(TpLoopBody, Dl, TII->get(ARM::t2LoopEnd))
11989 .addUse(RemainingLoopIterationsReg)
11990 .addMBB(TpLoopBody);
11991
11992 BuildMI(TpLoopBody, Dl, TII->get(ARM::t2B))
11993 .addMBB(TpExit)
11995}
11996
11998 // KCFI is supported in all ARM/Thumb modes
11999 return true;
12000}
12001
12005 const TargetInstrInfo *TII) const {
12006 assert(MBBI->isCall() && MBBI->getCFIType() &&
12007 "Invalid call instruction for a KCFI check");
12008
12009 MachineOperand *TargetOp = nullptr;
12010 switch (MBBI->getOpcode()) {
12011 // ARM mode opcodes
12012 case ARM::BLX:
12013 case ARM::BLX_pred:
12014 case ARM::BLX_noip:
12015 case ARM::BLX_pred_noip:
12016 case ARM::BX_CALL:
12017 TargetOp = &MBBI->getOperand(0);
12018 break;
12019 case ARM::TCRETURNri:
12020 case ARM::TCRETURNrinotr12:
12021 case ARM::TAILJMPr:
12022 case ARM::TAILJMPr4:
12023 TargetOp = &MBBI->getOperand(0);
12024 break;
12025 // Thumb mode opcodes (Thumb1 and Thumb2)
12026 // Note: Most Thumb call instructions have predicate operands before the
12027 // target register Format: tBLXr pred, predreg, target_register, ...
12028 case ARM::tBLXr: // Thumb1/Thumb2: BLX register (requires V5T)
12029 case ARM::tBLXr_noip: // Thumb1/Thumb2: BLX register, no IP clobber
12030 case ARM::tBX_CALL: // Thumb1 only: BX call (push LR, BX)
12031 TargetOp = &MBBI->getOperand(2);
12032 break;
12033 // Tail call instructions don't have predicates, target is operand 0
12034 case ARM::tTAILJMPr: // Thumb1/Thumb2: Tail call via register
12035 TargetOp = &MBBI->getOperand(0);
12036 break;
12037 default:
12038 llvm_unreachable("Unexpected CFI call opcode");
12039 }
12040
12041 assert(TargetOp && TargetOp->isReg() && "Invalid target operand");
12042 TargetOp->setIsRenamable(false);
12043
12044 // Select the appropriate KCFI_CHECK variant based on the instruction set
12045 unsigned KCFICheckOpcode;
12046 if (Subtarget->isThumb()) {
12047 if (Subtarget->isThumb2()) {
12048 KCFICheckOpcode = ARM::KCFI_CHECK_Thumb2;
12049 } else {
12050 KCFICheckOpcode = ARM::KCFI_CHECK_Thumb1;
12051 }
12052 } else {
12053 KCFICheckOpcode = ARM::KCFI_CHECK_ARM;
12054 }
12055
12056 return BuildMI(MBB, MBBI, MBBI->getDebugLoc(), TII->get(KCFICheckOpcode))
12057 .addReg(TargetOp->getReg())
12058 .addImm(MBBI->getCFIType())
12059 .getInstr();
12060}
12061
12064 MachineBasicBlock *BB) const {
12065 const TargetInstrInfo *TII = Subtarget->getInstrInfo();
12066 DebugLoc dl = MI.getDebugLoc();
12067 bool isThumb2 = Subtarget->isThumb2();
12068 switch (MI.getOpcode()) {
12069 default: {
12070 MI.print(errs());
12071 llvm_unreachable("Unexpected instr type to insert");
12072 }
12073
12074 // Thumb1 post-indexed loads are really just single-register LDMs.
12075 case ARM::tLDR_postidx: {
12076 MachineOperand Def(MI.getOperand(1));
12077 BuildMI(*BB, MI, dl, TII->get(ARM::tLDMIA_UPD))
12078 .add(Def) // Rn_wb
12079 .add(MI.getOperand(2)) // Rn
12080 .add(MI.getOperand(3)) // PredImm
12081 .add(MI.getOperand(4)) // PredReg
12082 .add(MI.getOperand(0)) // Rt
12083 .cloneMemRefs(MI);
12084 MI.eraseFromParent();
12085 return BB;
12086 }
12087
12088 case ARM::MVE_MEMCPYLOOPINST:
12089 case ARM::MVE_MEMSETLOOPINST: {
12090
12091 // Transformation below expands MVE_MEMCPYLOOPINST/MVE_MEMSETLOOPINST Pseudo
12092 // into a Tail Predicated (TP) Loop. It adds the instructions to calculate
12093 // the iteration count =ceil(size_in_bytes/16)) in the TP entry block and
12094 // adds the relevant instructions in the TP loop Body for generation of a
12095 // WLSTP loop.
12096
12097 // Below is relevant portion of the CFG after the transformation.
12098 // The Machine Basic Blocks are shown along with branch conditions (in
12099 // brackets). Note that TP entry/exit MBBs depict the entry/exit of this
12100 // portion of the CFG and may not necessarily be the entry/exit of the
12101 // function.
12102
12103 // (Relevant) CFG after transformation:
12104 // TP entry MBB
12105 // |
12106 // |-----------------|
12107 // (n <= 0) (n > 0)
12108 // | |
12109 // | TP loop Body MBB<--|
12110 // | | |
12111 // \ |___________|
12112 // \ /
12113 // TP exit MBB
12114
12115 MachineFunction *MF = BB->getParent();
12116 MachineFunctionProperties &Properties = MF->getProperties();
12117 MachineRegisterInfo &MRI = MF->getRegInfo();
12118
12119 Register OpDestReg = MI.getOperand(0).getReg();
12120 Register OpSrcReg = MI.getOperand(1).getReg();
12121 Register OpSizeReg = MI.getOperand(2).getReg();
12122
12123 // Allocate the required MBBs and add to parent function.
12124 MachineBasicBlock *TpEntry = BB;
12125 MachineBasicBlock *TpLoopBody = MF->CreateMachineBasicBlock();
12126 MachineBasicBlock *TpExit;
12127
12128 MF->push_back(TpLoopBody);
12129
12130 // If any instructions are present in the current block after
12131 // MVE_MEMCPYLOOPINST or MVE_MEMSETLOOPINST, split the current block and
12132 // move the instructions into the newly created exit block. If there are no
12133 // instructions add an explicit branch to the FallThrough block and then
12134 // split.
12135 //
12136 // The split is required for two reasons:
12137 // 1) A terminator(t2WhileLoopStart) will be placed at that site.
12138 // 2) Since a TPLoopBody will be added later, any phis in successive blocks
12139 // need to be updated. splitAt() already handles this.
12140 TpExit = BB->splitAt(MI, false);
12141 if (TpExit == BB) {
12142 assert(BB->canFallThrough() && "Exit Block must be Fallthrough of the "
12143 "block containing memcpy/memset Pseudo");
12144 TpExit = BB->getFallThrough();
12145 BuildMI(BB, dl, TII->get(ARM::t2B))
12146 .addMBB(TpExit)
12148 TpExit = BB->splitAt(MI, false);
12149 }
12150
12151 // Add logic for iteration count
12152 Register TotalIterationsReg =
12153 genTPEntry(TpEntry, TpLoopBody, TpExit, OpSizeReg, TII, dl, MRI);
12154
12155 // Add the vectorized (and predicated) loads/store instructions
12156 bool IsMemcpy = MI.getOpcode() == ARM::MVE_MEMCPYLOOPINST;
12157 genTPLoopBody(TpLoopBody, TpEntry, TpExit, TII, dl, MRI, OpSrcReg,
12158 OpDestReg, OpSizeReg, TotalIterationsReg, IsMemcpy);
12159
12160 // Required to avoid conflict with the MachineVerifier during testing.
12161 Properties.resetNoPHIs();
12162
12163 // Connect the blocks
12164 TpEntry->addSuccessor(TpLoopBody);
12165 TpLoopBody->addSuccessor(TpLoopBody);
12166 TpLoopBody->addSuccessor(TpExit);
12167
12168 // Reorder for a more natural layout
12169 TpLoopBody->moveAfter(TpEntry);
12170 TpExit->moveAfter(TpLoopBody);
12171
12172 // Finally, remove the memcpy Pseudo Instruction
12173 MI.eraseFromParent();
12174
12175 // Return the exit block as it may contain other instructions requiring a
12176 // custom inserter
12177 return TpExit;
12178 }
12179
12180 // The Thumb2 pre-indexed stores have the same MI operands, they just
12181 // define them differently in the .td files from the isel patterns, so
12182 // they need pseudos.
12183 case ARM::t2STR_preidx:
12184 MI.setDesc(TII->get(ARM::t2STR_PRE));
12185 return BB;
12186 case ARM::t2STRB_preidx:
12187 MI.setDesc(TII->get(ARM::t2STRB_PRE));
12188 return BB;
12189 case ARM::t2STRH_preidx:
12190 MI.setDesc(TII->get(ARM::t2STRH_PRE));
12191 return BB;
12192
12193 case ARM::STRi_preidx:
12194 case ARM::STRBi_preidx: {
12195 unsigned NewOpc = MI.getOpcode() == ARM::STRi_preidx ? ARM::STR_PRE_IMM
12196 : ARM::STRB_PRE_IMM;
12197 // Decode the offset.
12198 unsigned Offset = MI.getOperand(4).getImm();
12199 bool isSub = ARM_AM::getAM2Op(Offset) == ARM_AM::sub;
12201 if (isSub)
12202 Offset = -Offset;
12203
12204 MachineMemOperand *MMO = *MI.memoperands_begin();
12205 BuildMI(*BB, MI, dl, TII->get(NewOpc))
12206 .add(MI.getOperand(0)) // Rn_wb
12207 .add(MI.getOperand(1)) // Rt
12208 .add(MI.getOperand(2)) // Rn
12209 .addImm(Offset) // offset (skip GPR==zero_reg)
12210 .add(MI.getOperand(5)) // pred
12211 .add(MI.getOperand(6))
12212 .addMemOperand(MMO);
12213 MI.eraseFromParent();
12214 return BB;
12215 }
12216 case ARM::STRr_preidx:
12217 case ARM::STRBr_preidx:
12218 case ARM::STRH_preidx: {
12219 unsigned NewOpc;
12220 switch (MI.getOpcode()) {
12221 default: llvm_unreachable("unexpected opcode!");
12222 case ARM::STRr_preidx: NewOpc = ARM::STR_PRE_REG; break;
12223 case ARM::STRBr_preidx: NewOpc = ARM::STRB_PRE_REG; break;
12224 case ARM::STRH_preidx: NewOpc = ARM::STRH_PRE; break;
12225 }
12226 MachineInstrBuilder MIB = BuildMI(*BB, MI, dl, TII->get(NewOpc));
12227 for (const MachineOperand &MO : MI.operands())
12228 MIB.add(MO);
12229 MI.eraseFromParent();
12230 return BB;
12231 }
12232
12233 case ARM::tMOVCCr_pseudo: {
12234 // To "insert" a SELECT_CC instruction, we actually have to insert the
12235 // diamond control-flow pattern. The incoming instruction knows the
12236 // destination vreg to set, the condition code register to branch on, the
12237 // true/false values to select between, and a branch opcode to use.
12238 const BasicBlock *LLVM_BB = BB->getBasicBlock();
12240
12241 // thisMBB:
12242 // ...
12243 // TrueVal = ...
12244 // cmpTY ccX, r1, r2
12245 // bCC copy1MBB
12246 // fallthrough --> copy0MBB
12247 MachineBasicBlock *thisMBB = BB;
12248 MachineFunction *F = BB->getParent();
12249 MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);
12250 MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB);
12251 F->insert(It, copy0MBB);
12252 F->insert(It, sinkMBB);
12253
12254 // Set the call frame size on entry to the new basic blocks.
12255 unsigned CallFrameSize = TII->getCallFrameSizeAt(MI);
12256 copy0MBB->setCallFrameSize(CallFrameSize);
12257 sinkMBB->setCallFrameSize(CallFrameSize);
12258
12259 // Check whether CPSR is live past the tMOVCCr_pseudo.
12260 const TargetRegisterInfo *TRI = Subtarget->getRegisterInfo();
12261 if (!MI.killsRegister(ARM::CPSR, /*TRI=*/nullptr) &&
12262 !checkAndUpdateCPSRKill(MI, thisMBB, TRI)) {
12263 copy0MBB->addLiveIn(ARM::CPSR);
12264 sinkMBB->addLiveIn(ARM::CPSR);
12265 }
12266
12267 // Transfer the remainder of BB and its successor edges to sinkMBB.
12268 sinkMBB->splice(sinkMBB->begin(), BB,
12269 std::next(MachineBasicBlock::iterator(MI)), BB->end());
12271
12272 BB->addSuccessor(copy0MBB);
12273 BB->addSuccessor(sinkMBB);
12274
12275 BuildMI(BB, dl, TII->get(ARM::tBcc))
12276 .addMBB(sinkMBB)
12277 .addImm(MI.getOperand(3).getImm())
12278 .addReg(MI.getOperand(4).getReg());
12279
12280 // copy0MBB:
12281 // %FalseValue = ...
12282 // # fallthrough to sinkMBB
12283 BB = copy0MBB;
12284
12285 // Update machine-CFG edges
12286 BB->addSuccessor(sinkMBB);
12287
12288 // sinkMBB:
12289 // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ]
12290 // ...
12291 BB = sinkMBB;
12292 BuildMI(*BB, BB->begin(), dl, TII->get(ARM::PHI), MI.getOperand(0).getReg())
12293 .addReg(MI.getOperand(1).getReg())
12294 .addMBB(copy0MBB)
12295 .addReg(MI.getOperand(2).getReg())
12296 .addMBB(thisMBB);
12297
12298 MI.eraseFromParent(); // The pseudo instruction is gone now.
12299 return BB;
12300 }
12301
12302 case ARM::BCCi64:
12303 case ARM::BCCZi64: {
12304 // If there is an unconditional branch to the other successor, remove it.
12305 BB->erase(std::next(MachineBasicBlock::iterator(MI)), BB->end());
12306
12307 // Compare both parts that make up the double comparison separately for
12308 // equality.
12309 bool RHSisZero = MI.getOpcode() == ARM::BCCZi64;
12310
12311 Register LHS1 = MI.getOperand(1).getReg();
12312 Register LHS2 = MI.getOperand(2).getReg();
12313 if (RHSisZero) {
12314 BuildMI(BB, dl, TII->get(isThumb2 ? ARM::t2CMPri : ARM::CMPri))
12315 .addReg(LHS1)
12316 .addImm(0)
12318 BuildMI(BB, dl, TII->get(isThumb2 ? ARM::t2CMPri : ARM::CMPri))
12319 .addReg(LHS2).addImm(0)
12320 .addImm(ARMCC::EQ).addReg(ARM::CPSR);
12321 } else {
12322 Register RHS1 = MI.getOperand(3).getReg();
12323 Register RHS2 = MI.getOperand(4).getReg();
12324 BuildMI(BB, dl, TII->get(isThumb2 ? ARM::t2CMPrr : ARM::CMPrr))
12325 .addReg(LHS1)
12326 .addReg(RHS1)
12328 BuildMI(BB, dl, TII->get(isThumb2 ? ARM::t2CMPrr : ARM::CMPrr))
12329 .addReg(LHS2).addReg(RHS2)
12330 .addImm(ARMCC::EQ).addReg(ARM::CPSR);
12331 }
12332
12333 MachineBasicBlock *destMBB = MI.getOperand(RHSisZero ? 3 : 5).getMBB();
12334 MachineBasicBlock *exitMBB = OtherSucc(BB, destMBB);
12335 if (MI.getOperand(0).getImm() == ARMCC::NE)
12336 std::swap(destMBB, exitMBB);
12337
12338 BuildMI(BB, dl, TII->get(isThumb2 ? ARM::t2Bcc : ARM::Bcc))
12339 .addMBB(destMBB).addImm(ARMCC::EQ).addReg(ARM::CPSR);
12340 if (isThumb2)
12341 BuildMI(BB, dl, TII->get(ARM::t2B))
12342 .addMBB(exitMBB)
12344 else
12345 BuildMI(BB, dl, TII->get(ARM::B)) .addMBB(exitMBB);
12346
12347 MI.eraseFromParent(); // The pseudo instruction is gone now.
12348 return BB;
12349 }
12350
12351 case ARM::Int_eh_sjlj_setjmp:
12352 case ARM::Int_eh_sjlj_setjmp_nofp:
12353 case ARM::tInt_eh_sjlj_setjmp:
12354 case ARM::t2Int_eh_sjlj_setjmp:
12355 case ARM::t2Int_eh_sjlj_setjmp_nofp:
12356 return BB;
12357
12358 case ARM::Int_eh_sjlj_setup_dispatch:
12359 EmitSjLjDispatchBlock(MI, BB);
12360 return BB;
12361 case ARM::COPY_STRUCT_BYVAL_I32:
12362 ++NumLoopByVals;
12363 return EmitStructByval(MI, BB);
12364 case ARM::WIN__CHKSTK:
12365 return EmitLowered__chkstk(MI, BB);
12366 case ARM::WIN__DBZCHK:
12367 return EmitLowered__dbzchk(MI, BB);
12368 }
12369}
12370
12371/// Attaches vregs to MEMCPY that it will use as scratch registers
12372/// when it is expanded into LDM/STM. This is done as a post-isel lowering
12373/// instead of as a custom inserter because we need the use list from the SDNode.
12374static void attachMEMCPYScratchRegs(const ARMSubtarget *Subtarget,
12375 MachineInstr &MI, const SDNode *Node) {
12376 bool isThumb1 = Subtarget->isThumb1Only();
12377
12378 MachineFunction *MF = MI.getParent()->getParent();
12379 MachineRegisterInfo &MRI = MF->getRegInfo();
12380 MachineInstrBuilder MIB(*MF, MI);
12381
12382 // If the new dst/src is unused mark it as dead.
12383 if (!Node->hasAnyUseOfValue(0)) {
12384 MI.getOperand(0).setIsDead(true);
12385 }
12386 if (!Node->hasAnyUseOfValue(1)) {
12387 MI.getOperand(1).setIsDead(true);
12388 }
12389
12390 // The MEMCPY both defines and kills the scratch registers.
12391 for (unsigned I = 0; I != MI.getOperand(4).getImm(); ++I) {
12392 Register TmpReg = MRI.createVirtualRegister(isThumb1 ? &ARM::tGPRRegClass
12393 : &ARM::GPRRegClass);
12395 }
12396}
12397
12399 SDNode *Node) const {
12400 if (MI.getOpcode() == ARM::MEMCPY) {
12401 attachMEMCPYScratchRegs(Subtarget, MI, Node);
12402 return;
12403 }
12404
12405 const MCInstrDesc *MCID = &MI.getDesc();
12406 // Adjust potentially 's' setting instructions after isel, i.e. ADC, SBC, RSB,
12407 // RSC. Coming out of isel, they have an implicit CPSR def, but the optional
12408 // operand is still set to noreg. If needed, set the optional operand's
12409 // register to CPSR, and remove the redundant implicit def.
12410 //
12411 // e.g. ADCS (..., implicit-def CPSR) -> ADC (... opt:def CPSR).
12412
12413 // Rename pseudo opcodes.
12414 unsigned NewOpc = convertAddSubFlagsOpcode(MI.getOpcode());
12415 unsigned ccOutIdx;
12416 if (NewOpc) {
12417 const ARMBaseInstrInfo *TII = Subtarget->getInstrInfo();
12418 MCID = &TII->get(NewOpc);
12419
12420 assert(MCID->getNumOperands() ==
12421 MI.getDesc().getNumOperands() + 5 - MI.getDesc().getSize()
12422 && "converted opcode should be the same except for cc_out"
12423 " (and, on Thumb1, pred)");
12424
12425 MI.setDesc(*MCID);
12426
12427 // Add the optional cc_out operand
12428 MI.addOperand(MachineOperand::CreateReg(0, /*isDef=*/true));
12429
12430 // On Thumb1, move all input operands to the end, then add the predicate
12431 if (Subtarget->isThumb1Only()) {
12432 for (unsigned c = MCID->getNumOperands() - 4; c--;) {
12433 MI.addOperand(MI.getOperand(1));
12434 MI.removeOperand(1);
12435 }
12436
12437 // Restore the ties
12438 for (unsigned i = MI.getNumOperands(); i--;) {
12439 const MachineOperand& op = MI.getOperand(i);
12440 if (op.isReg() && op.isUse()) {
12441 int DefIdx = MCID->getOperandConstraint(i, MCOI::TIED_TO);
12442 if (DefIdx != -1)
12443 MI.tieOperands(DefIdx, i);
12444 }
12445 }
12446
12448 MI.addOperand(MachineOperand::CreateReg(0, /*isDef=*/false));
12449 ccOutIdx = 1;
12450 } else
12451 ccOutIdx = MCID->getNumOperands() - 1;
12452 } else
12453 ccOutIdx = MCID->getNumOperands() - 1;
12454
12455 // Any ARM instruction that sets the 's' bit should specify an optional
12456 // "cc_out" operand in the last operand position.
12457 if (!MI.hasOptionalDef() || !MCID->operands()[ccOutIdx].isOptionalDef()) {
12458 assert(!NewOpc && "Optional cc_out operand required");
12459 return;
12460 }
12461 // Look for an implicit def of CPSR added by MachineInstr ctor. Remove it
12462 // since we already have an optional CPSR def.
12463 bool definesCPSR = false;
12464 bool deadCPSR = false;
12465 for (unsigned i = MCID->getNumOperands(), e = MI.getNumOperands(); i != e;
12466 ++i) {
12467 const MachineOperand &MO = MI.getOperand(i);
12468 if (MO.isReg() && MO.isDef() && MO.getReg() == ARM::CPSR) {
12469 definesCPSR = true;
12470 if (MO.isDead())
12471 deadCPSR = true;
12472 MI.removeOperand(i);
12473 break;
12474 }
12475 }
12476 if (!definesCPSR) {
12477 assert(!NewOpc && "Optional cc_out operand required");
12478 return;
12479 }
12480 assert(deadCPSR == !Node->hasAnyUseOfValue(1) && "inconsistent dead flag");
12481 if (deadCPSR) {
12482 assert(!MI.getOperand(ccOutIdx).getReg() &&
12483 "expect uninitialized optional cc_out operand");
12484 // Thumb1 instructions must have the S bit even if the CPSR is dead.
12485 if (!Subtarget->isThumb1Only())
12486 return;
12487 }
12488
12489 // If this instruction was defined with an optional CPSR def and its dag node
12490 // had a live implicit CPSR def, then activate the optional CPSR def.
12491 MachineOperand &MO = MI.getOperand(ccOutIdx);
12492 MO.setReg(ARM::CPSR);
12493 MO.setIsDef(true);
12494}
12495
12496//===----------------------------------------------------------------------===//
12497// ARM Optimization Hooks
12498//===----------------------------------------------------------------------===//
12499
12500// Helper function that checks if N is a null or all ones constant.
12501static inline bool isZeroOrAllOnes(SDValue N, bool AllOnes) {
12503}
12504
12505// Return true if N is conditionally 0 or all ones.
12506// Detects these expressions where cc is an i1 value:
12507//
12508// (select cc 0, y) [AllOnes=0]
12509// (select cc y, 0) [AllOnes=0]
12510// (zext cc) [AllOnes=0]
12511// (sext cc) [AllOnes=0/1]
12512// (select cc -1, y) [AllOnes=1]
12513// (select cc y, -1) [AllOnes=1]
12514//
12515// Invert is set when N is the null/all ones constant when CC is false.
12516// OtherOp is set to the alternative value of N.
12518 SDValue &CC, bool &Invert,
12519 SDValue &OtherOp,
12520 SelectionDAG &DAG) {
12521 switch (N->getOpcode()) {
12522 default: return false;
12523 case ISD::SELECT: {
12524 CC = N->getOperand(0);
12525 SDValue N1 = N->getOperand(1);
12526 SDValue N2 = N->getOperand(2);
12527 if (isZeroOrAllOnes(N1, AllOnes)) {
12528 Invert = false;
12529 OtherOp = N2;
12530 return true;
12531 }
12532 if (isZeroOrAllOnes(N2, AllOnes)) {
12533 Invert = true;
12534 OtherOp = N1;
12535 return true;
12536 }
12537 return false;
12538 }
12539 case ISD::ZERO_EXTEND:
12540 // (zext cc) can never be the all ones value.
12541 if (AllOnes)
12542 return false;
12543 [[fallthrough]];
12544 case ISD::SIGN_EXTEND: {
12545 SDLoc dl(N);
12546 EVT VT = N->getValueType(0);
12547 CC = N->getOperand(0);
12548 if (CC.getValueType() != MVT::i1 || CC.getOpcode() != ISD::SETCC)
12549 return false;
12550 Invert = !AllOnes;
12551 if (AllOnes)
12552 // When looking for an AllOnes constant, N is an sext, and the 'other'
12553 // value is 0.
12554 OtherOp = DAG.getConstant(0, dl, VT);
12555 else if (N->getOpcode() == ISD::ZERO_EXTEND)
12556 // When looking for a 0 constant, N can be zext or sext.
12557 OtherOp = DAG.getConstant(1, dl, VT);
12558 else
12559 OtherOp = DAG.getAllOnesConstant(dl, VT);
12560 return true;
12561 }
12562 }
12563}
12564
12565// Combine a constant select operand into its use:
12566//
12567// (add (select cc, 0, c), x) -> (select cc, x, (add, x, c))
12568// (sub x, (select cc, 0, c)) -> (select cc, x, (sub, x, c))
12569// (and (select cc, -1, c), x) -> (select cc, x, (and, x, c)) [AllOnes=1]
12570// (or (select cc, 0, c), x) -> (select cc, x, (or, x, c))
12571// (xor (select cc, 0, c), x) -> (select cc, x, (xor, x, c))
12572//
12573// The transform is rejected if the select doesn't have a constant operand that
12574// is null, or all ones when AllOnes is set.
12575//
12576// Also recognize sext/zext from i1:
12577//
12578// (add (zext cc), x) -> (select cc (add x, 1), x)
12579// (add (sext cc), x) -> (select cc (add x, -1), x)
12580//
12581// These transformations eventually create predicated instructions.
12582//
12583// @param N The node to transform.
12584// @param Slct The N operand that is a select.
12585// @param OtherOp The other N operand (x above).
12586// @param DCI Context.
12587// @param AllOnes Require the select constant to be all ones instead of null.
12588// @returns The new node, or SDValue() on failure.
12589static
12592 bool AllOnes = false) {
12593 SelectionDAG &DAG = DCI.DAG;
12594 EVT VT = N->getValueType(0);
12595 SDValue NonConstantVal;
12596 SDValue CCOp;
12597 bool SwapSelectOps;
12598 if (!isConditionalZeroOrAllOnes(Slct.getNode(), AllOnes, CCOp, SwapSelectOps,
12599 NonConstantVal, DAG))
12600 return SDValue();
12601
12602 // Slct is now know to be the desired identity constant when CC is true.
12603 SDValue TrueVal = OtherOp;
12604 SDValue FalseVal = DAG.getNode(N->getOpcode(), SDLoc(N), VT,
12605 OtherOp, NonConstantVal);
12606 // Unless SwapSelectOps says CC should be false.
12607 if (SwapSelectOps)
12608 std::swap(TrueVal, FalseVal);
12609
12610 return DAG.getNode(ISD::SELECT, SDLoc(N), VT,
12611 CCOp, TrueVal, FalseVal);
12612}
12613
12614// Attempt combineSelectAndUse on each operand of a commutative operator N.
12615static
12618 SDValue N0 = N->getOperand(0);
12619 SDValue N1 = N->getOperand(1);
12620 if (N0.getNode()->hasOneUse())
12621 if (SDValue Result = combineSelectAndUse(N, N0, N1, DCI, AllOnes))
12622 return Result;
12623 if (N1.getNode()->hasOneUse())
12624 if (SDValue Result = combineSelectAndUse(N, N1, N0, DCI, AllOnes))
12625 return Result;
12626 return SDValue();
12627}
12628
12630 // VUZP shuffle node.
12631 if (N->getOpcode() == ARMISD::VUZP)
12632 return true;
12633
12634 // "VUZP" on i32 is an alias for VTRN.
12635 if (N->getOpcode() == ARMISD::VTRN && N->getValueType(0) == MVT::v2i32)
12636 return true;
12637
12638 return false;
12639}
12640
12643 const ARMSubtarget *Subtarget) {
12644 // Look for ADD(VUZP.0, VUZP.1).
12645 if (!IsVUZPShuffleNode(N0.getNode()) || N0.getNode() != N1.getNode() ||
12646 N0 == N1)
12647 return SDValue();
12648
12649 // Make sure the ADD is a 64-bit add; there is no 128-bit VPADD.
12650 if (!N->getValueType(0).is64BitVector())
12651 return SDValue();
12652
12653 // Generate vpadd.
12654 SelectionDAG &DAG = DCI.DAG;
12655 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
12656 SDLoc dl(N);
12657 SDNode *Unzip = N0.getNode();
12658 EVT VT = N->getValueType(0);
12659
12661 Ops.push_back(DAG.getConstant(Intrinsic::arm_neon_vpadd, dl,
12662 TLI.getPointerTy(DAG.getDataLayout())));
12663 Ops.push_back(Unzip->getOperand(0));
12664 Ops.push_back(Unzip->getOperand(1));
12665
12666 return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, VT, Ops);
12667}
12668
12671 const ARMSubtarget *Subtarget) {
12672 // Check for two extended operands.
12673 if (!(N0.getOpcode() == ISD::SIGN_EXTEND &&
12674 N1.getOpcode() == ISD::SIGN_EXTEND) &&
12675 !(N0.getOpcode() == ISD::ZERO_EXTEND &&
12676 N1.getOpcode() == ISD::ZERO_EXTEND))
12677 return SDValue();
12678
12679 SDValue N00 = N0.getOperand(0);
12680 SDValue N10 = N1.getOperand(0);
12681
12682 // Look for ADD(SEXT(VUZP.0), SEXT(VUZP.1))
12683 if (!IsVUZPShuffleNode(N00.getNode()) || N00.getNode() != N10.getNode() ||
12684 N00 == N10)
12685 return SDValue();
12686
12687 // We only recognize Q register paddl here; this can't be reached until
12688 // after type legalization.
12689 if (!N00.getValueType().is64BitVector() ||
12691 return SDValue();
12692
12693 // Generate vpaddl.
12694 SelectionDAG &DAG = DCI.DAG;
12695 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
12696 SDLoc dl(N);
12697 EVT VT = N->getValueType(0);
12698
12700 // Form vpaddl.sN or vpaddl.uN depending on the kind of extension.
12701 unsigned Opcode;
12702 if (N0.getOpcode() == ISD::SIGN_EXTEND)
12703 Opcode = Intrinsic::arm_neon_vpaddls;
12704 else
12705 Opcode = Intrinsic::arm_neon_vpaddlu;
12706 Ops.push_back(DAG.getConstant(Opcode, dl,
12707 TLI.getPointerTy(DAG.getDataLayout())));
12709 unsigned NumElts = VT.getVectorNumElements();
12710 EVT ConcatVT = EVT::getVectorVT(*DAG.getContext(), ElemTy, NumElts * 2);
12711 SDValue Concat = DAG.getNode(ISD::CONCAT_VECTORS, SDLoc(N), ConcatVT,
12712 N00.getOperand(0), N00.getOperand(1));
12713 Ops.push_back(Concat);
12714
12715 return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, VT, Ops);
12716}
12717
12718// FIXME: This function shouldn't be necessary; if we lower BUILD_VECTOR in
12719// an appropriate manner, we end up with ADD(VUZP(ZEXT(N))), which is
12720// much easier to match.
12721static SDValue
12724 const ARMSubtarget *Subtarget) {
12725 // Only perform optimization if after legalize, and if NEON is available. We
12726 // also expected both operands to be BUILD_VECTORs.
12727 if (DCI.isBeforeLegalize() || !Subtarget->hasNEON()
12728 || N0.getOpcode() != ISD::BUILD_VECTOR
12729 || N1.getOpcode() != ISD::BUILD_VECTOR)
12730 return SDValue();
12731
12732 // Check output type since VPADDL operand elements can only be 8, 16, or 32.
12733 EVT VT = N->getValueType(0);
12734 if (!VT.isInteger() || VT.getVectorElementType() == MVT::i64)
12735 return SDValue();
12736
12737 // Check that the vector operands are of the right form.
12738 // N0 and N1 are BUILD_VECTOR nodes with N number of EXTRACT_VECTOR
12739 // operands, where N is the size of the formed vector.
12740 // Each EXTRACT_VECTOR should have the same input vector and odd or even
12741 // index such that we have a pair wise add pattern.
12742
12743 // Grab the vector that all EXTRACT_VECTOR nodes should be referencing.
12745 return SDValue();
12746 SDValue Vec = N0->getOperand(0)->getOperand(0);
12747 SDNode *V = Vec.getNode();
12748 unsigned nextIndex = 0;
12749
12750 // For each operands to the ADD which are BUILD_VECTORs,
12751 // check to see if each of their operands are an EXTRACT_VECTOR with
12752 // the same vector and appropriate index.
12753 for (unsigned i = 0, e = N0->getNumOperands(); i != e; ++i) {
12756
12757 SDValue ExtVec0 = N0->getOperand(i);
12758 SDValue ExtVec1 = N1->getOperand(i);
12759
12760 // First operand is the vector, verify its the same.
12761 if (V != ExtVec0->getOperand(0).getNode() ||
12762 V != ExtVec1->getOperand(0).getNode())
12763 return SDValue();
12764
12765 // Second is the constant, verify its correct.
12768
12769 // For the constant, we want to see all the even or all the odd.
12770 if (!C0 || !C1 || C0->getZExtValue() != nextIndex
12771 || C1->getZExtValue() != nextIndex+1)
12772 return SDValue();
12773
12774 // Increment index.
12775 nextIndex+=2;
12776 } else
12777 return SDValue();
12778 }
12779
12780 // Don't generate vpaddl+vmovn; we'll match it to vpadd later. Also make sure
12781 // we're using the entire input vector, otherwise there's a size/legality
12782 // mismatch somewhere.
12783 if (nextIndex != Vec.getValueType().getVectorNumElements() ||
12785 return SDValue();
12786
12787 // Create VPADDL node.
12788 SelectionDAG &DAG = DCI.DAG;
12789 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
12790
12791 SDLoc dl(N);
12792
12793 // Build operand list.
12795 Ops.push_back(DAG.getConstant(Intrinsic::arm_neon_vpaddls, dl,
12796 TLI.getPointerTy(DAG.getDataLayout())));
12797
12798 // Input is the vector.
12799 Ops.push_back(Vec);
12800
12801 // Get widened type and narrowed type.
12802 MVT widenType;
12803 unsigned numElem = VT.getVectorNumElements();
12804
12805 EVT inputLaneType = Vec.getValueType().getVectorElementType();
12806 switch (inputLaneType.getSimpleVT().SimpleTy) {
12807 case MVT::i8: widenType = MVT::getVectorVT(MVT::i16, numElem); break;
12808 case MVT::i16: widenType = MVT::getVectorVT(MVT::i32, numElem); break;
12809 case MVT::i32: widenType = MVT::getVectorVT(MVT::i64, numElem); break;
12810 default:
12811 llvm_unreachable("Invalid vector element type for padd optimization.");
12812 }
12813
12814 SDValue tmp = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, widenType, Ops);
12815 unsigned ExtOp = VT.bitsGT(tmp.getValueType()) ? ISD::ANY_EXTEND : ISD::TRUNCATE;
12816 return DAG.getNode(ExtOp, dl, VT, tmp);
12817}
12818
12820 if (V->getOpcode() == ISD::UMUL_LOHI ||
12821 V->getOpcode() == ISD::SMUL_LOHI)
12822 return V;
12823 return SDValue();
12824}
12825
12826static SDValue AddCombineTo64BitSMLAL16(SDNode *AddcNode, SDNode *AddeNode,
12828 const ARMSubtarget *Subtarget) {
12829 if (!Subtarget->hasBaseDSP())
12830 return SDValue();
12831
12832 // SMLALBB, SMLALBT, SMLALTB, SMLALTT multiply two 16-bit values and
12833 // accumulates the product into a 64-bit value. The 16-bit values will
12834 // be sign extended somehow or SRA'd into 32-bit values
12835 // (addc (adde (mul 16bit, 16bit), lo), hi)
12836 SDValue Mul = AddcNode->getOperand(0);
12837 SDValue Lo = AddcNode->getOperand(1);
12838 if (Mul.getOpcode() != ISD::MUL) {
12839 Lo = AddcNode->getOperand(0);
12840 Mul = AddcNode->getOperand(1);
12841 if (Mul.getOpcode() != ISD::MUL)
12842 return SDValue();
12843 }
12844
12845 SDValue SRA = AddeNode->getOperand(0);
12846 SDValue Hi = AddeNode->getOperand(1);
12847 if (SRA.getOpcode() != ISD::SRA) {
12848 SRA = AddeNode->getOperand(1);
12849 Hi = AddeNode->getOperand(0);
12850 if (SRA.getOpcode() != ISD::SRA)
12851 return SDValue();
12852 }
12853 if (auto Const = dyn_cast<ConstantSDNode>(SRA.getOperand(1))) {
12854 if (Const->getZExtValue() != 31)
12855 return SDValue();
12856 } else
12857 return SDValue();
12858
12859 if (SRA.getOperand(0) != Mul)
12860 return SDValue();
12861
12862 SelectionDAG &DAG = DCI.DAG;
12863 SDLoc dl(AddcNode);
12864 unsigned Opcode = 0;
12865 SDValue Op0;
12866 SDValue Op1;
12867
12868 if (isS16(Mul.getOperand(0), DAG) && isS16(Mul.getOperand(1), DAG)) {
12869 Opcode = ARMISD::SMLALBB;
12870 Op0 = Mul.getOperand(0);
12871 Op1 = Mul.getOperand(1);
12872 } else if (isS16(Mul.getOperand(0), DAG) && isSRA16(Mul.getOperand(1))) {
12873 Opcode = ARMISD::SMLALBT;
12874 Op0 = Mul.getOperand(0);
12875 Op1 = Mul.getOperand(1).getOperand(0);
12876 } else if (isSRA16(Mul.getOperand(0)) && isS16(Mul.getOperand(1), DAG)) {
12877 Opcode = ARMISD::SMLALTB;
12878 Op0 = Mul.getOperand(0).getOperand(0);
12879 Op1 = Mul.getOperand(1);
12880 } else if (isSRA16(Mul.getOperand(0)) && isSRA16(Mul.getOperand(1))) {
12881 Opcode = ARMISD::SMLALTT;
12882 Op0 = Mul->getOperand(0).getOperand(0);
12883 Op1 = Mul->getOperand(1).getOperand(0);
12884 }
12885
12886 if (!Op0 || !Op1)
12887 return SDValue();
12888
12889 SDValue SMLAL = DAG.getNode(Opcode, dl, DAG.getVTList(MVT::i32, MVT::i32),
12890 Op0, Op1, Lo, Hi);
12891 // Replace the ADDs' nodes uses by the MLA node's values.
12892 SDValue HiMLALResult(SMLAL.getNode(), 1);
12893 SDValue LoMLALResult(SMLAL.getNode(), 0);
12894
12895 DAG.ReplaceAllUsesOfValueWith(SDValue(AddcNode, 0), LoMLALResult);
12896 DAG.ReplaceAllUsesOfValueWith(SDValue(AddeNode, 0), HiMLALResult);
12897
12898 // Return original node to notify the driver to stop replacing.
12899 SDValue resNode(AddcNode, 0);
12900 return resNode;
12901}
12902
12905 const ARMSubtarget *Subtarget) {
12906 // Look for multiply add opportunities.
12907 // The pattern is a ISD::UMUL_LOHI followed by two add nodes, where
12908 // each add nodes consumes a value from ISD::UMUL_LOHI and there is
12909 // a glue link from the first add to the second add.
12910 // If we find this pattern, we can replace the U/SMUL_LOHI, ADDC, and ADDE by
12911 // a S/UMLAL instruction.
12912 // UMUL_LOHI
12913 // / :lo \ :hi
12914 // V \ [no multiline comment]
12915 // loAdd -> ADDC |
12916 // \ :carry /
12917 // V V
12918 // ADDE <- hiAdd
12919 //
12920 // In the special case where only the higher part of a signed result is used
12921 // and the add to the low part of the result of ISD::UMUL_LOHI adds or subtracts
12922 // a constant with the exact value of 0x80000000, we recognize we are dealing
12923 // with a "rounded multiply and add" (or subtract) and transform it into
12924 // either a ARMISD::SMMLAR or ARMISD::SMMLSR respectively.
12925
12926 assert((AddeSubeNode->getOpcode() == ARMISD::ADDE ||
12927 AddeSubeNode->getOpcode() == ARMISD::SUBE) &&
12928 "Expect an ADDE or SUBE");
12929
12930 assert(AddeSubeNode->getNumOperands() == 3 &&
12931 AddeSubeNode->getOperand(2).getValueType() == MVT::i32 &&
12932 "ADDE node has the wrong inputs");
12933
12934 // Check that we are chained to the right ADDC or SUBC node.
12935 SDNode *AddcSubcNode = AddeSubeNode->getOperand(2).getNode();
12936 if ((AddeSubeNode->getOpcode() == ARMISD::ADDE &&
12937 AddcSubcNode->getOpcode() != ARMISD::ADDC) ||
12938 (AddeSubeNode->getOpcode() == ARMISD::SUBE &&
12939 AddcSubcNode->getOpcode() != ARMISD::SUBC))
12940 return SDValue();
12941
12942 SDValue AddcSubcOp0 = AddcSubcNode->getOperand(0);
12943 SDValue AddcSubcOp1 = AddcSubcNode->getOperand(1);
12944
12945 // Check if the two operands are from the same mul_lohi node.
12946 if (AddcSubcOp0.getNode() == AddcSubcOp1.getNode())
12947 return SDValue();
12948
12949 assert(AddcSubcNode->getNumValues() == 2 &&
12950 AddcSubcNode->getValueType(0) == MVT::i32 &&
12951 "Expect ADDC with two result values. First: i32");
12952
12953 // Check that the ADDC adds the low result of the S/UMUL_LOHI. If not, it
12954 // maybe a SMLAL which multiplies two 16-bit values.
12955 if (AddeSubeNode->getOpcode() == ARMISD::ADDE &&
12956 AddcSubcOp0->getOpcode() != ISD::UMUL_LOHI &&
12957 AddcSubcOp0->getOpcode() != ISD::SMUL_LOHI &&
12958 AddcSubcOp1->getOpcode() != ISD::UMUL_LOHI &&
12959 AddcSubcOp1->getOpcode() != ISD::SMUL_LOHI)
12960 return AddCombineTo64BitSMLAL16(AddcSubcNode, AddeSubeNode, DCI, Subtarget);
12961
12962 // Check for the triangle shape.
12963 SDValue AddeSubeOp0 = AddeSubeNode->getOperand(0);
12964 SDValue AddeSubeOp1 = AddeSubeNode->getOperand(1);
12965
12966 // Make sure that the ADDE/SUBE operands are not coming from the same node.
12967 if (AddeSubeOp0.getNode() == AddeSubeOp1.getNode())
12968 return SDValue();
12969
12970 // Find the MUL_LOHI node walking up ADDE/SUBE's operands.
12971 bool IsLeftOperandMUL = false;
12972 SDValue MULOp = findMUL_LOHI(AddeSubeOp0);
12973 if (MULOp == SDValue())
12974 MULOp = findMUL_LOHI(AddeSubeOp1);
12975 else
12976 IsLeftOperandMUL = true;
12977 if (MULOp == SDValue())
12978 return SDValue();
12979
12980 // Figure out the right opcode.
12981 unsigned Opc = MULOp->getOpcode();
12982 unsigned FinalOpc = (Opc == ISD::SMUL_LOHI) ? ARMISD::SMLAL : ARMISD::UMLAL;
12983
12984 // Figure out the high and low input values to the MLAL node.
12985 SDValue *HiAddSub = nullptr;
12986 SDValue *LoMul = nullptr;
12987 SDValue *LowAddSub = nullptr;
12988
12989 // Ensure that ADDE/SUBE is from high result of ISD::xMUL_LOHI.
12990 if ((AddeSubeOp0 != MULOp.getValue(1)) && (AddeSubeOp1 != MULOp.getValue(1)))
12991 return SDValue();
12992
12993 if (IsLeftOperandMUL)
12994 HiAddSub = &AddeSubeOp1;
12995 else
12996 HiAddSub = &AddeSubeOp0;
12997
12998 // Ensure that LoMul and LowAddSub are taken from correct ISD::SMUL_LOHI node
12999 // whose low result is fed to the ADDC/SUBC we are checking.
13000
13001 if (AddcSubcOp0 == MULOp.getValue(0)) {
13002 LoMul = &AddcSubcOp0;
13003 LowAddSub = &AddcSubcOp1;
13004 }
13005 if (AddcSubcOp1 == MULOp.getValue(0)) {
13006 LoMul = &AddcSubcOp1;
13007 LowAddSub = &AddcSubcOp0;
13008 }
13009
13010 if (!LoMul)
13011 return SDValue();
13012
13013 // If HiAddSub is the same node as ADDC/SUBC or is a predecessor of ADDC/SUBC
13014 // the replacement below will create a cycle.
13015 if (AddcSubcNode == HiAddSub->getNode() ||
13016 AddcSubcNode->isPredecessorOf(HiAddSub->getNode()))
13017 return SDValue();
13018
13019 // Create the merged node.
13020 SelectionDAG &DAG = DCI.DAG;
13021
13022 // Start building operand list.
13024 Ops.push_back(LoMul->getOperand(0));
13025 Ops.push_back(LoMul->getOperand(1));
13026
13027 // Check whether we can use SMMLAR, SMMLSR or SMMULR instead. For this to be
13028 // the case, we must be doing signed multiplication and only use the higher
13029 // part of the result of the MLAL, furthermore the LowAddSub must be a constant
13030 // addition or subtraction with the value of 0x800000.
13031 if (Subtarget->hasV6Ops() && Subtarget->hasDSP() && Subtarget->useMulOps() &&
13032 FinalOpc == ARMISD::SMLAL && !AddeSubeNode->hasAnyUseOfValue(1) &&
13033 LowAddSub->getNode()->getOpcode() == ISD::Constant &&
13034 static_cast<ConstantSDNode *>(LowAddSub->getNode())->getZExtValue() ==
13035 0x80000000) {
13036 Ops.push_back(*HiAddSub);
13037 if (AddcSubcNode->getOpcode() == ARMISD::SUBC) {
13038 FinalOpc = ARMISD::SMMLSR;
13039 } else {
13040 FinalOpc = ARMISD::SMMLAR;
13041 }
13042 SDValue NewNode = DAG.getNode(FinalOpc, SDLoc(AddcSubcNode), MVT::i32, Ops);
13043 DAG.ReplaceAllUsesOfValueWith(SDValue(AddeSubeNode, 0), NewNode);
13044
13045 return SDValue(AddeSubeNode, 0);
13046 } else if (AddcSubcNode->getOpcode() == ARMISD::SUBC)
13047 // SMMLS is generated during instruction selection and the rest of this
13048 // function can not handle the case where AddcSubcNode is a SUBC.
13049 return SDValue();
13050
13051 // Finish building the operand list for {U/S}MLAL
13052 Ops.push_back(*LowAddSub);
13053 Ops.push_back(*HiAddSub);
13054
13055 SDValue MLALNode = DAG.getNode(FinalOpc, SDLoc(AddcSubcNode),
13056 DAG.getVTList(MVT::i32, MVT::i32), Ops);
13057
13058 // Replace the ADDs' nodes uses by the MLA node's values.
13059 SDValue HiMLALResult(MLALNode.getNode(), 1);
13060 DAG.ReplaceAllUsesOfValueWith(SDValue(AddeSubeNode, 0), HiMLALResult);
13061
13062 SDValue LoMLALResult(MLALNode.getNode(), 0);
13063 DAG.ReplaceAllUsesOfValueWith(SDValue(AddcSubcNode, 0), LoMLALResult);
13064
13065 // Return original node to notify the driver to stop replacing.
13066 return SDValue(AddeSubeNode, 0);
13067}
13068
13071 const ARMSubtarget *Subtarget) {
13072 // UMAAL is similar to UMLAL except that it adds two unsigned values.
13073 // While trying to combine for the other MLAL nodes, first search for the
13074 // chance to use UMAAL. Check if Addc uses a node which has already
13075 // been combined into a UMLAL. The other pattern is UMLAL using Addc/Adde
13076 // as the addend, and it's handled in PerformUMLALCombine.
13077
13078 if (!Subtarget->hasV6Ops() || !Subtarget->hasDSP())
13079 return AddCombineTo64bitMLAL(AddeNode, DCI, Subtarget);
13080
13081 // Check that we have a glued ADDC node.
13082 SDNode* AddcNode = AddeNode->getOperand(2).getNode();
13083 if (AddcNode->getOpcode() != ARMISD::ADDC)
13084 return SDValue();
13085
13086 // Find the converted UMAAL or quit if it doesn't exist.
13087 SDNode *UmlalNode = nullptr;
13088 SDValue AddHi;
13089 if (AddcNode->getOperand(0).getOpcode() == ARMISD::UMLAL) {
13090 UmlalNode = AddcNode->getOperand(0).getNode();
13091 AddHi = AddcNode->getOperand(1);
13092 } else if (AddcNode->getOperand(1).getOpcode() == ARMISD::UMLAL) {
13093 UmlalNode = AddcNode->getOperand(1).getNode();
13094 AddHi = AddcNode->getOperand(0);
13095 } else {
13096 return AddCombineTo64bitMLAL(AddeNode, DCI, Subtarget);
13097 }
13098
13099 // The ADDC should be glued to an ADDE node, which uses the same UMLAL as
13100 // the ADDC as well as Zero.
13101 if (!isNullConstant(UmlalNode->getOperand(3)))
13102 return SDValue();
13103
13104 if ((isNullConstant(AddeNode->getOperand(0)) &&
13105 AddeNode->getOperand(1).getNode() == UmlalNode) ||
13106 (AddeNode->getOperand(0).getNode() == UmlalNode &&
13107 isNullConstant(AddeNode->getOperand(1)))) {
13108 SelectionDAG &DAG = DCI.DAG;
13109 SDValue Ops[] = { UmlalNode->getOperand(0), UmlalNode->getOperand(1),
13110 UmlalNode->getOperand(2), AddHi };
13111 SDValue UMAAL = DAG.getNode(ARMISD::UMAAL, SDLoc(AddcNode),
13112 DAG.getVTList(MVT::i32, MVT::i32), Ops);
13113
13114 // Replace the ADDs' nodes uses by the UMAAL node's values.
13115 DAG.ReplaceAllUsesOfValueWith(SDValue(AddeNode, 0), SDValue(UMAAL.getNode(), 1));
13116 DAG.ReplaceAllUsesOfValueWith(SDValue(AddcNode, 0), SDValue(UMAAL.getNode(), 0));
13117
13118 // Return original node to notify the driver to stop replacing.
13119 return SDValue(AddeNode, 0);
13120 }
13121 return SDValue();
13122}
13123
13125 const ARMSubtarget *Subtarget) {
13126 if (!Subtarget->hasV6Ops() || !Subtarget->hasDSP())
13127 return SDValue();
13128
13129 // Check that we have a pair of ADDC and ADDE as operands.
13130 // Both addends of the ADDE must be zero.
13131 SDNode* AddcNode = N->getOperand(2).getNode();
13132 SDNode* AddeNode = N->getOperand(3).getNode();
13133 if ((AddcNode->getOpcode() == ARMISD::ADDC) &&
13134 (AddeNode->getOpcode() == ARMISD::ADDE) &&
13135 isNullConstant(AddeNode->getOperand(0)) &&
13136 isNullConstant(AddeNode->getOperand(1)) &&
13137 (AddeNode->getOperand(2).getNode() == AddcNode))
13138 return DAG.getNode(ARMISD::UMAAL, SDLoc(N),
13139 DAG.getVTList(MVT::i32, MVT::i32),
13140 {N->getOperand(0), N->getOperand(1),
13141 AddcNode->getOperand(0), AddcNode->getOperand(1)});
13142 else
13143 return SDValue();
13144}
13145
13148 const ARMSubtarget *Subtarget) {
13149 SelectionDAG &DAG(DCI.DAG);
13150
13151 if (N->getOpcode() == ARMISD::SUBC && N->hasAnyUseOfValue(1)) {
13152 // (SUBC (ADDE 0, 0, C), 1) -> C
13153 SDValue LHS = N->getOperand(0);
13154 SDValue RHS = N->getOperand(1);
13155 if (LHS->getOpcode() == ARMISD::ADDE &&
13156 isNullConstant(LHS->getOperand(0)) &&
13157 isNullConstant(LHS->getOperand(1)) && isOneConstant(RHS)) {
13158 return DCI.CombineTo(N, SDValue(N, 0), LHS->getOperand(2));
13159 }
13160 }
13161
13162 if (Subtarget->isThumb1Only()) {
13163 SDValue RHS = N->getOperand(1);
13165 int32_t imm = C->getSExtValue();
13166 if (imm < 0 && imm > std::numeric_limits<int>::min()) {
13167 SDLoc DL(N);
13168 RHS = DAG.getConstant(-imm, DL, MVT::i32);
13169 unsigned Opcode = (N->getOpcode() == ARMISD::ADDC) ? ARMISD::SUBC
13170 : ARMISD::ADDC;
13171 return DAG.getNode(Opcode, DL, N->getVTList(), N->getOperand(0), RHS);
13172 }
13173 }
13174 }
13175
13176 return SDValue();
13177}
13178
13181 const ARMSubtarget *Subtarget) {
13182 if (Subtarget->isThumb1Only()) {
13183 SelectionDAG &DAG = DCI.DAG;
13184 SDValue RHS = N->getOperand(1);
13186 int64_t imm = C->getSExtValue();
13187 if (imm < 0) {
13188 SDLoc DL(N);
13189
13190 // The with-carry-in form matches bitwise not instead of the negation.
13191 // Effectively, the inverse interpretation of the carry flag already
13192 // accounts for part of the negation.
13193 RHS = DAG.getConstant(~imm, DL, MVT::i32);
13194
13195 unsigned Opcode = (N->getOpcode() == ARMISD::ADDE) ? ARMISD::SUBE
13196 : ARMISD::ADDE;
13197 return DAG.getNode(Opcode, DL, N->getVTList(),
13198 N->getOperand(0), RHS, N->getOperand(2));
13199 }
13200 }
13201 } else if (N->getOperand(1)->getOpcode() == ISD::SMUL_LOHI) {
13202 return AddCombineTo64bitMLAL(N, DCI, Subtarget);
13203 }
13204 return SDValue();
13205}
13206
13209 const ARMSubtarget *Subtarget) {
13210 if (!Subtarget->hasMVEIntegerOps())
13211 return SDValue();
13212
13213 SDLoc dl(N);
13214 SDValue SetCC;
13215 SDValue LHS;
13216 SDValue RHS;
13217 ISD::CondCode CC;
13218 SDValue TrueVal;
13219 SDValue FalseVal;
13220
13221 if (N->getOpcode() == ISD::SELECT &&
13222 N->getOperand(0)->getOpcode() == ISD::SETCC) {
13223 SetCC = N->getOperand(0);
13224 LHS = SetCC->getOperand(0);
13225 RHS = SetCC->getOperand(1);
13226 CC = cast<CondCodeSDNode>(SetCC->getOperand(2))->get();
13227 TrueVal = N->getOperand(1);
13228 FalseVal = N->getOperand(2);
13229 } else if (N->getOpcode() == ISD::SELECT_CC) {
13230 LHS = N->getOperand(0);
13231 RHS = N->getOperand(1);
13232 CC = cast<CondCodeSDNode>(N->getOperand(4))->get();
13233 TrueVal = N->getOperand(2);
13234 FalseVal = N->getOperand(3);
13235 } else {
13236 return SDValue();
13237 }
13238
13239 unsigned int Opcode = 0;
13240 if ((TrueVal->getOpcode() == ISD::VECREDUCE_UMIN ||
13241 FalseVal->getOpcode() == ISD::VECREDUCE_UMIN) &&
13242 (CC == ISD::SETULT || CC == ISD::SETUGT)) {
13243 Opcode = ARMISD::VMINVu;
13244 if (CC == ISD::SETUGT)
13245 std::swap(TrueVal, FalseVal);
13246 } else if ((TrueVal->getOpcode() == ISD::VECREDUCE_SMIN ||
13247 FalseVal->getOpcode() == ISD::VECREDUCE_SMIN) &&
13248 (CC == ISD::SETLT || CC == ISD::SETGT)) {
13249 Opcode = ARMISD::VMINVs;
13250 if (CC == ISD::SETGT)
13251 std::swap(TrueVal, FalseVal);
13252 } else if ((TrueVal->getOpcode() == ISD::VECREDUCE_UMAX ||
13253 FalseVal->getOpcode() == ISD::VECREDUCE_UMAX) &&
13254 (CC == ISD::SETUGT || CC == ISD::SETULT)) {
13255 Opcode = ARMISD::VMAXVu;
13256 if (CC == ISD::SETULT)
13257 std::swap(TrueVal, FalseVal);
13258 } else if ((TrueVal->getOpcode() == ISD::VECREDUCE_SMAX ||
13259 FalseVal->getOpcode() == ISD::VECREDUCE_SMAX) &&
13260 (CC == ISD::SETGT || CC == ISD::SETLT)) {
13261 Opcode = ARMISD::VMAXVs;
13262 if (CC == ISD::SETLT)
13263 std::swap(TrueVal, FalseVal);
13264 } else
13265 return SDValue();
13266
13267 // Normalise to the right hand side being the vector reduction
13268 switch (TrueVal->getOpcode()) {
13273 std::swap(LHS, RHS);
13274 std::swap(TrueVal, FalseVal);
13275 break;
13276 }
13277
13278 EVT VectorType = FalseVal->getOperand(0).getValueType();
13279
13280 if (VectorType != MVT::v16i8 && VectorType != MVT::v8i16 &&
13281 VectorType != MVT::v4i32)
13282 return SDValue();
13283
13284 EVT VectorScalarType = VectorType.getVectorElementType();
13285
13286 // The values being selected must also be the ones being compared
13287 if (TrueVal != LHS || FalseVal != RHS)
13288 return SDValue();
13289
13290 EVT LeftType = LHS->getValueType(0);
13291 EVT RightType = RHS->getValueType(0);
13292
13293 // The types must match the reduced type too
13294 if (LeftType != VectorScalarType || RightType != VectorScalarType)
13295 return SDValue();
13296
13297 // Legalise the scalar to an i32
13298 if (VectorScalarType != MVT::i32)
13299 LHS = DCI.DAG.getNode(ISD::ANY_EXTEND, dl, MVT::i32, LHS);
13300
13301 // Generate the reduction as an i32 for legalisation purposes
13302 auto Reduction =
13303 DCI.DAG.getNode(Opcode, dl, MVT::i32, LHS, RHS->getOperand(0));
13304
13305 // The result isn't actually an i32 so truncate it back to its original type
13306 if (VectorScalarType != MVT::i32)
13307 Reduction = DCI.DAG.getNode(ISD::TRUNCATE, dl, VectorScalarType, Reduction);
13308
13309 return Reduction;
13310}
13311
13312// A special combine for the vqdmulh family of instructions. This is one of the
13313// potential set of patterns that could patch this instruction. The base pattern
13314// you would expect to be min(max(ashr(mul(mul(sext(x), 2), sext(y)), 16))).
13315// This matches the different min(max(ashr(mul(mul(sext(x), sext(y)), 2), 16))),
13316// which llvm will have optimized to min(ashr(mul(sext(x), sext(y)), 15))) as
13317// the max is unnecessary.
13319 EVT VT = N->getValueType(0);
13320 SDValue Shft;
13321 ConstantSDNode *Clamp;
13322
13323 if (!VT.isVector() || VT.getScalarSizeInBits() > 64)
13324 return SDValue();
13325
13326 if (N->getOpcode() == ISD::SMIN) {
13327 Shft = N->getOperand(0);
13328 Clamp = isConstOrConstSplat(N->getOperand(1));
13329 } else if (N->getOpcode() == ISD::VSELECT) {
13330 // Detect a SMIN, which for an i64 node will be a vselect/setcc, not a smin.
13331 SDValue Cmp = N->getOperand(0);
13332 if (Cmp.getOpcode() != ISD::SETCC ||
13333 cast<CondCodeSDNode>(Cmp.getOperand(2))->get() != ISD::SETLT ||
13334 Cmp.getOperand(0) != N->getOperand(1) ||
13335 Cmp.getOperand(1) != N->getOperand(2))
13336 return SDValue();
13337 Shft = N->getOperand(1);
13338 Clamp = isConstOrConstSplat(N->getOperand(2));
13339 } else
13340 return SDValue();
13341
13342 if (!Clamp)
13343 return SDValue();
13344
13345 MVT ScalarType;
13346 int ShftAmt = 0;
13347 switch (Clamp->getSExtValue()) {
13348 case (1 << 7) - 1:
13349 ScalarType = MVT::i8;
13350 ShftAmt = 7;
13351 break;
13352 case (1 << 15) - 1:
13353 ScalarType = MVT::i16;
13354 ShftAmt = 15;
13355 break;
13356 case (1ULL << 31) - 1:
13357 ScalarType = MVT::i32;
13358 ShftAmt = 31;
13359 break;
13360 default:
13361 return SDValue();
13362 }
13363
13364 if (Shft.getOpcode() != ISD::SRA)
13365 return SDValue();
13367 if (!N1 || N1->getSExtValue() != ShftAmt)
13368 return SDValue();
13369
13370 SDValue Mul = Shft.getOperand(0);
13371 if (Mul.getOpcode() != ISD::MUL)
13372 return SDValue();
13373
13374 SDValue Ext0 = Mul.getOperand(0);
13375 SDValue Ext1 = Mul.getOperand(1);
13376 if (Ext0.getOpcode() != ISD::SIGN_EXTEND ||
13377 Ext1.getOpcode() != ISD::SIGN_EXTEND)
13378 return SDValue();
13379 EVT VecVT = Ext0.getOperand(0).getValueType();
13380 if (!VecVT.isPow2VectorType() || VecVT.getVectorNumElements() == 1)
13381 return SDValue();
13382 if (Ext1.getOperand(0).getValueType() != VecVT ||
13383 VecVT.getScalarType() != ScalarType ||
13384 VT.getScalarSizeInBits() < ScalarType.getScalarSizeInBits() * 2)
13385 return SDValue();
13386
13387 SDLoc DL(Mul);
13388 unsigned LegalLanes = 128 / (ShftAmt + 1);
13389 EVT LegalVecVT = MVT::getVectorVT(ScalarType, LegalLanes);
13390 // For types smaller than legal vectors extend to be legal and only use needed
13391 // lanes.
13392 if (VecVT.getSizeInBits() < 128) {
13393 EVT ExtVecVT =
13395 VecVT.getVectorNumElements());
13396 SDValue Inp0 =
13397 DAG.getNode(ISD::ANY_EXTEND, DL, ExtVecVT, Ext0.getOperand(0));
13398 SDValue Inp1 =
13399 DAG.getNode(ISD::ANY_EXTEND, DL, ExtVecVT, Ext1.getOperand(0));
13400 Inp0 = DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, LegalVecVT, Inp0);
13401 Inp1 = DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, LegalVecVT, Inp1);
13402 SDValue VQDMULH = DAG.getNode(ARMISD::VQDMULH, DL, LegalVecVT, Inp0, Inp1);
13403 SDValue Trunc = DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, ExtVecVT, VQDMULH);
13404 Trunc = DAG.getNode(ISD::TRUNCATE, DL, VecVT, Trunc);
13405 return DAG.getNode(ISD::SIGN_EXTEND, DL, VT, Trunc);
13406 }
13407
13408 // For larger types, split into legal sized chunks.
13409 assert(VecVT.getSizeInBits() % 128 == 0 && "Expected a power2 type");
13410 unsigned NumParts = VecVT.getSizeInBits() / 128;
13412 for (unsigned I = 0; I < NumParts; ++I) {
13413 SDValue Inp0 =
13414 DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, LegalVecVT, Ext0.getOperand(0),
13415 DAG.getVectorIdxConstant(I * LegalLanes, DL));
13416 SDValue Inp1 =
13417 DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, LegalVecVT, Ext1.getOperand(0),
13418 DAG.getVectorIdxConstant(I * LegalLanes, DL));
13419 SDValue VQDMULH = DAG.getNode(ARMISD::VQDMULH, DL, LegalVecVT, Inp0, Inp1);
13420 Parts.push_back(VQDMULH);
13421 }
13422 return DAG.getNode(ISD::SIGN_EXTEND, DL, VT,
13423 DAG.getNode(ISD::CONCAT_VECTORS, DL, VecVT, Parts));
13424}
13425
13428 const ARMSubtarget *Subtarget) {
13429 if (!Subtarget->hasMVEIntegerOps())
13430 return SDValue();
13431
13432 // Constant fold vselect 0, A, B -> B
13433 // and vselect 0xffff, A, B -> A
13434 if (N->getOperand(0).getOpcode() == ARMISD::PREDICATE_CAST &&
13435 isa<ConstantSDNode>(N->getOperand(0).getOperand(0))) {
13436 unsigned C = N->getOperand(0).getConstantOperandVal(0);
13437 if (C == 0)
13438 return N->getOperand(2);
13439 if (C == 0xffff)
13440 return N->getOperand(1);
13441 }
13442
13443 if (SDValue V = PerformVQDMULHCombine(N, DCI.DAG))
13444 return V;
13445
13446 // Transforms vselect(not(cond), lhs, rhs) into vselect(cond, rhs, lhs).
13447 //
13448 // We need to re-implement this optimization here as the implementation in the
13449 // Target-Independent DAGCombiner does not handle the kind of constant we make
13450 // (it calls isConstOrConstSplat with AllowTruncation set to false - and for
13451 // good reason, allowing truncation there would break other targets).
13452 //
13453 // Currently, this is only done for MVE, as it's the only target that benefits
13454 // from this transformation (e.g. VPNOT+VPSEL becomes a single VPSEL).
13455 if (N->getOperand(0).getOpcode() != ISD::XOR)
13456 return SDValue();
13457 SDValue XOR = N->getOperand(0);
13458
13459 // Check if the XOR's RHS is either a 1, or a BUILD_VECTOR of 1s.
13460 // It is important to check with truncation allowed as the BUILD_VECTORs we
13461 // generate in those situations will truncate their operands.
13462 ConstantSDNode *Const =
13463 isConstOrConstSplat(XOR->getOperand(1), /*AllowUndefs*/ false,
13464 /*AllowTruncation*/ true);
13465 if (!Const || !Const->isOne())
13466 return SDValue();
13467
13468 // Rewrite into vselect(cond, rhs, lhs).
13469 SDValue Cond = XOR->getOperand(0);
13470 SDValue LHS = N->getOperand(1);
13471 SDValue RHS = N->getOperand(2);
13472 EVT Type = N->getValueType(0);
13473 return DCI.DAG.getNode(ISD::VSELECT, SDLoc(N), Type, Cond, RHS, LHS);
13474}
13475
13476// Convert vsetcc([0,1,2,..], splat(n), ult) -> vctp n
13479 const ARMSubtarget *Subtarget) {
13480 SDValue Op0 = N->getOperand(0);
13481 SDValue Op1 = N->getOperand(1);
13482 ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(2))->get();
13483 EVT VT = N->getValueType(0);
13484
13485 if (!Subtarget->hasMVEIntegerOps() ||
13487 return SDValue();
13488
13489 if (CC == ISD::SETUGT) {
13490 std::swap(Op0, Op1);
13491 CC = ISD::SETULT;
13492 }
13493
13494 if (CC != ISD::SETULT || VT.getScalarSizeInBits() != 1 ||
13496 return SDValue();
13497
13498 // Check first operand is BuildVector of 0,1,2,...
13499 for (unsigned I = 0; I < VT.getVectorNumElements(); I++) {
13500 if (!Op0.getOperand(I).isUndef() &&
13502 Op0.getConstantOperandVal(I) == I))
13503 return SDValue();
13504 }
13505
13506 // The second is a Splat of Op1S
13507 SDValue Op1S = DCI.DAG.getSplatValue(Op1);
13508 if (!Op1S)
13509 return SDValue();
13510
13511 unsigned Opc;
13512 switch (VT.getVectorNumElements()) {
13513 case 4:
13514 Opc = Intrinsic::arm_mve_vctp32;
13515 break;
13516 case 8:
13517 Opc = Intrinsic::arm_mve_vctp16;
13518 break;
13519 case 16:
13520 Opc = Intrinsic::arm_mve_vctp8;
13521 break;
13522 default:
13523 return SDValue();
13524 }
13525
13526 SDLoc DL(N);
13527 return DCI.DAG.getNode(ISD::INTRINSIC_WO_CHAIN, DL, VT,
13528 DCI.DAG.getConstant(Opc, DL, MVT::i32),
13529 DCI.DAG.getZExtOrTrunc(Op1S, DL, MVT::i32));
13530}
13531
13532/// PerformADDECombine - Target-specific dag combine transform from
13533/// ARMISD::ADDC, ARMISD::ADDE, and ISD::MUL_LOHI to MLAL or
13534/// ARMISD::ADDC, ARMISD::ADDE and ARMISD::UMLAL to ARMISD::UMAAL
13537 const ARMSubtarget *Subtarget) {
13538 // Only ARM and Thumb2 support UMLAL/SMLAL.
13539 if (Subtarget->isThumb1Only())
13540 return PerformAddeSubeCombine(N, DCI, Subtarget);
13541
13542 // Only perform the checks after legalize when the pattern is available.
13543 if (DCI.isBeforeLegalize()) return SDValue();
13544
13545 return AddCombineTo64bitUMAAL(N, DCI, Subtarget);
13546}
13547
13548/// PerformADDCombineWithOperands - Try DAG combinations for an ADD with
13549/// operands N0 and N1. This is a helper for PerformADDCombine that is
13550/// called with the default operands, and if that fails, with commuted
13551/// operands.
13554 const ARMSubtarget *Subtarget){
13555 // Attempt to create vpadd for this add.
13556 if (SDValue Result = AddCombineToVPADD(N, N0, N1, DCI, Subtarget))
13557 return Result;
13558
13559 // Attempt to create vpaddl for this add.
13560 if (SDValue Result = AddCombineVUZPToVPADDL(N, N0, N1, DCI, Subtarget))
13561 return Result;
13562 if (SDValue Result = AddCombineBUILD_VECTORToVPADDL(N, N0, N1, DCI,
13563 Subtarget))
13564 return Result;
13565
13566 // fold (add (select cc, 0, c), x) -> (select cc, x, (add, x, c))
13567 if (N0.getNode()->hasOneUse())
13568 if (SDValue Result = combineSelectAndUse(N, N0, N1, DCI))
13569 return Result;
13570 return SDValue();
13571}
13572
13574 EVT VT = N->getValueType(0);
13575 SDValue N0 = N->getOperand(0);
13576 SDValue N1 = N->getOperand(1);
13577 SDLoc dl(N);
13578
13579 auto IsVecReduce = [](SDValue Op) {
13580 switch (Op.getOpcode()) {
13581 case ISD::VECREDUCE_ADD:
13582 case ARMISD::VADDVs:
13583 case ARMISD::VADDVu:
13584 case ARMISD::VMLAVs:
13585 case ARMISD::VMLAVu:
13586 return true;
13587 }
13588 return false;
13589 };
13590
13591 auto DistrubuteAddAddVecReduce = [&](SDValue N0, SDValue N1) {
13592 // Distribute add(X, add(vecreduce(Y), vecreduce(Z))) ->
13593 // add(add(X, vecreduce(Y)), vecreduce(Z))
13594 // to make better use of vaddva style instructions.
13595 if (VT == MVT::i32 && N1.getOpcode() == ISD::ADD && !IsVecReduce(N0) &&
13596 IsVecReduce(N1.getOperand(0)) && IsVecReduce(N1.getOperand(1)) &&
13597 !isa<ConstantSDNode>(N0) && N1->hasOneUse()) {
13598 SDValue Add0 = DAG.getNode(ISD::ADD, dl, VT, N0, N1.getOperand(0));
13599 return DAG.getNode(ISD::ADD, dl, VT, Add0, N1.getOperand(1));
13600 }
13601 // And turn add(add(A, reduce(B)), add(C, reduce(D))) ->
13602 // add(add(add(A, C), reduce(B)), reduce(D))
13603 if (VT == MVT::i32 && N0.getOpcode() == ISD::ADD &&
13604 N1.getOpcode() == ISD::ADD && N0->hasOneUse() && N1->hasOneUse()) {
13605 unsigned N0RedOp = 0;
13606 if (!IsVecReduce(N0.getOperand(N0RedOp))) {
13607 N0RedOp = 1;
13608 if (!IsVecReduce(N0.getOperand(N0RedOp)))
13609 return SDValue();
13610 }
13611
13612 unsigned N1RedOp = 0;
13613 if (!IsVecReduce(N1.getOperand(N1RedOp)))
13614 N1RedOp = 1;
13615 if (!IsVecReduce(N1.getOperand(N1RedOp)))
13616 return SDValue();
13617
13618 SDValue Add0 = DAG.getNode(ISD::ADD, dl, VT, N0.getOperand(1 - N0RedOp),
13619 N1.getOperand(1 - N1RedOp));
13620 SDValue Add1 =
13621 DAG.getNode(ISD::ADD, dl, VT, Add0, N0.getOperand(N0RedOp));
13622 return DAG.getNode(ISD::ADD, dl, VT, Add1, N1.getOperand(N1RedOp));
13623 }
13624 return SDValue();
13625 };
13626 if (SDValue R = DistrubuteAddAddVecReduce(N0, N1))
13627 return R;
13628 if (SDValue R = DistrubuteAddAddVecReduce(N1, N0))
13629 return R;
13630
13631 // Distribute add(vecreduce(load(Y)), vecreduce(load(Z)))
13632 // Or add(add(X, vecreduce(load(Y))), vecreduce(load(Z)))
13633 // by ascending load offsets. This can help cores prefetch if the order of
13634 // loads is more predictable.
13635 auto DistrubuteVecReduceLoad = [&](SDValue N0, SDValue N1, bool IsForward) {
13636 // Check if two reductions are known to load data where one is before/after
13637 // another. Return negative if N0 loads data before N1, positive if N1 is
13638 // before N0 and 0 otherwise if nothing is known.
13639 auto IsKnownOrderedLoad = [&](SDValue N0, SDValue N1) {
13640 // Look through to the first operand of a MUL, for the VMLA case.
13641 // Currently only looks at the first operand, in the hope they are equal.
13642 if (N0.getOpcode() == ISD::MUL)
13643 N0 = N0.getOperand(0);
13644 if (N1.getOpcode() == ISD::MUL)
13645 N1 = N1.getOperand(0);
13646
13647 // Return true if the two operands are loads to the same object and the
13648 // offset of the first is known to be less than the offset of the second.
13649 LoadSDNode *Load0 = dyn_cast<LoadSDNode>(N0);
13650 LoadSDNode *Load1 = dyn_cast<LoadSDNode>(N1);
13651 if (!Load0 || !Load1 || Load0->getChain() != Load1->getChain() ||
13652 !Load0->isSimple() || !Load1->isSimple() || Load0->isIndexed() ||
13653 Load1->isIndexed())
13654 return 0;
13655
13656 auto BaseLocDecomp0 = BaseIndexOffset::match(Load0, DAG);
13657 auto BaseLocDecomp1 = BaseIndexOffset::match(Load1, DAG);
13658
13659 if (!BaseLocDecomp0.getBase() ||
13660 BaseLocDecomp0.getBase() != BaseLocDecomp1.getBase() ||
13661 !BaseLocDecomp0.hasValidOffset() || !BaseLocDecomp1.hasValidOffset())
13662 return 0;
13663 if (BaseLocDecomp0.getOffset() < BaseLocDecomp1.getOffset())
13664 return -1;
13665 if (BaseLocDecomp0.getOffset() > BaseLocDecomp1.getOffset())
13666 return 1;
13667 return 0;
13668 };
13669
13670 SDValue X;
13671 if (N0.getOpcode() == ISD::ADD && N0->hasOneUse()) {
13672 if (IsVecReduce(N0.getOperand(0)) && IsVecReduce(N0.getOperand(1))) {
13673 int IsBefore = IsKnownOrderedLoad(N0.getOperand(0).getOperand(0),
13674 N0.getOperand(1).getOperand(0));
13675 if (IsBefore < 0) {
13676 X = N0.getOperand(0);
13677 N0 = N0.getOperand(1);
13678 } else if (IsBefore > 0) {
13679 X = N0.getOperand(1);
13680 N0 = N0.getOperand(0);
13681 } else
13682 return SDValue();
13683 } else if (IsVecReduce(N0.getOperand(0))) {
13684 X = N0.getOperand(1);
13685 N0 = N0.getOperand(0);
13686 } else if (IsVecReduce(N0.getOperand(1))) {
13687 X = N0.getOperand(0);
13688 N0 = N0.getOperand(1);
13689 } else
13690 return SDValue();
13691 } else if (IsForward && IsVecReduce(N0) && IsVecReduce(N1) &&
13692 IsKnownOrderedLoad(N0.getOperand(0), N1.getOperand(0)) < 0) {
13693 // Note this is backward to how you would expect. We create
13694 // add(reduce(load + 16), reduce(load + 0)) so that the
13695 // add(reduce(load+16), X) is combined into VADDVA(X, load+16)), leaving
13696 // the X as VADDV(load + 0)
13697 return DAG.getNode(ISD::ADD, dl, VT, N1, N0);
13698 } else
13699 return SDValue();
13700
13701 if (!IsVecReduce(N0) || !IsVecReduce(N1))
13702 return SDValue();
13703
13704 if (IsKnownOrderedLoad(N1.getOperand(0), N0.getOperand(0)) >= 0)
13705 return SDValue();
13706
13707 // Switch from add(add(X, N0), N1) to add(add(X, N1), N0)
13708 SDValue Add0 = DAG.getNode(ISD::ADD, dl, VT, X, N1);
13709 return DAG.getNode(ISD::ADD, dl, VT, Add0, N0);
13710 };
13711 if (SDValue R = DistrubuteVecReduceLoad(N0, N1, true))
13712 return R;
13713 if (SDValue R = DistrubuteVecReduceLoad(N1, N0, false))
13714 return R;
13715 return SDValue();
13716}
13717
13719 const ARMSubtarget *Subtarget) {
13720 if (!Subtarget->hasMVEIntegerOps())
13721 return SDValue();
13722
13724 return R;
13725
13726 EVT VT = N->getValueType(0);
13727 SDValue N0 = N->getOperand(0);
13728 SDValue N1 = N->getOperand(1);
13729 SDLoc dl(N);
13730
13731 if (VT != MVT::i64)
13732 return SDValue();
13733
13734 // We are looking for a i64 add of a VADDLVx. Due to these being i64's, this
13735 // will look like:
13736 // t1: i32,i32 = ARMISD::VADDLVs x
13737 // t2: i64 = build_pair t1, t1:1
13738 // t3: i64 = add t2, y
13739 // Otherwise we try to push the add up above VADDLVAx, to potentially allow
13740 // the add to be simplified separately.
13741 // We also need to check for sext / zext and commutitive adds.
13742 auto MakeVecReduce = [&](unsigned Opcode, unsigned OpcodeA, SDValue NA,
13743 SDValue NB) {
13744 if (NB->getOpcode() != ISD::BUILD_PAIR)
13745 return SDValue();
13746 SDValue VecRed = NB->getOperand(0);
13747 if ((VecRed->getOpcode() != Opcode && VecRed->getOpcode() != OpcodeA) ||
13748 VecRed.getResNo() != 0 ||
13749 NB->getOperand(1) != SDValue(VecRed.getNode(), 1))
13750 return SDValue();
13751
13752 if (VecRed->getOpcode() == OpcodeA) {
13753 // add(NA, VADDLVA(Inp), Y) -> VADDLVA(add(NA, Inp), Y)
13754 SDValue Inp = DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64,
13755 VecRed.getOperand(0), VecRed.getOperand(1));
13756 NA = DAG.getNode(ISD::ADD, dl, MVT::i64, Inp, NA);
13757 }
13758
13760 std::tie(Ops[0], Ops[1]) = DAG.SplitScalar(NA, dl, MVT::i32, MVT::i32);
13761
13762 unsigned S = VecRed->getOpcode() == OpcodeA ? 2 : 0;
13763 for (unsigned I = S, E = VecRed.getNumOperands(); I < E; I++)
13764 Ops.push_back(VecRed->getOperand(I));
13765 SDValue Red =
13766 DAG.getNode(OpcodeA, dl, DAG.getVTList({MVT::i32, MVT::i32}), Ops);
13767 return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Red,
13768 SDValue(Red.getNode(), 1));
13769 };
13770
13771 if (SDValue M = MakeVecReduce(ARMISD::VADDLVs, ARMISD::VADDLVAs, N0, N1))
13772 return M;
13773 if (SDValue M = MakeVecReduce(ARMISD::VADDLVu, ARMISD::VADDLVAu, N0, N1))
13774 return M;
13775 if (SDValue M = MakeVecReduce(ARMISD::VADDLVs, ARMISD::VADDLVAs, N1, N0))
13776 return M;
13777 if (SDValue M = MakeVecReduce(ARMISD::VADDLVu, ARMISD::VADDLVAu, N1, N0))
13778 return M;
13779 if (SDValue M = MakeVecReduce(ARMISD::VADDLVps, ARMISD::VADDLVAps, N0, N1))
13780 return M;
13781 if (SDValue M = MakeVecReduce(ARMISD::VADDLVpu, ARMISD::VADDLVApu, N0, N1))
13782 return M;
13783 if (SDValue M = MakeVecReduce(ARMISD::VADDLVps, ARMISD::VADDLVAps, N1, N0))
13784 return M;
13785 if (SDValue M = MakeVecReduce(ARMISD::VADDLVpu, ARMISD::VADDLVApu, N1, N0))
13786 return M;
13787 if (SDValue M = MakeVecReduce(ARMISD::VMLALVs, ARMISD::VMLALVAs, N0, N1))
13788 return M;
13789 if (SDValue M = MakeVecReduce(ARMISD::VMLALVu, ARMISD::VMLALVAu, N0, N1))
13790 return M;
13791 if (SDValue M = MakeVecReduce(ARMISD::VMLALVs, ARMISD::VMLALVAs, N1, N0))
13792 return M;
13793 if (SDValue M = MakeVecReduce(ARMISD::VMLALVu, ARMISD::VMLALVAu, N1, N0))
13794 return M;
13795 if (SDValue M = MakeVecReduce(ARMISD::VMLALVps, ARMISD::VMLALVAps, N0, N1))
13796 return M;
13797 if (SDValue M = MakeVecReduce(ARMISD::VMLALVpu, ARMISD::VMLALVApu, N0, N1))
13798 return M;
13799 if (SDValue M = MakeVecReduce(ARMISD::VMLALVps, ARMISD::VMLALVAps, N1, N0))
13800 return M;
13801 if (SDValue M = MakeVecReduce(ARMISD::VMLALVpu, ARMISD::VMLALVApu, N1, N0))
13802 return M;
13803 return SDValue();
13804}
13805
13806bool
13808 CombineLevel Level) const {
13809 assert((N->getOpcode() == ISD::SHL || N->getOpcode() == ISD::SRA ||
13810 N->getOpcode() == ISD::SRL) &&
13811 "Expected shift op");
13812
13813 SDValue ShiftLHS = N->getOperand(0);
13814 if (!ShiftLHS->hasOneUse())
13815 return false;
13816
13817 if (ShiftLHS.getOpcode() == ISD::SIGN_EXTEND &&
13818 !ShiftLHS.getOperand(0)->hasOneUse())
13819 return false;
13820
13821 if (Level == BeforeLegalizeTypes)
13822 return true;
13823
13824 if (N->getOpcode() != ISD::SHL)
13825 return true;
13826
13827 if (Subtarget->isThumb1Only()) {
13828 // Avoid making expensive immediates by commuting shifts. (This logic
13829 // only applies to Thumb1 because ARM and Thumb2 immediates can be shifted
13830 // for free.)
13831 if (N->getOpcode() != ISD::SHL)
13832 return true;
13833 SDValue N1 = N->getOperand(0);
13834 if (N1->getOpcode() != ISD::ADD && N1->getOpcode() != ISD::AND &&
13835 N1->getOpcode() != ISD::OR && N1->getOpcode() != ISD::XOR)
13836 return true;
13837 if (auto *Const = dyn_cast<ConstantSDNode>(N1->getOperand(1))) {
13838 if (Const->getAPIntValue().ult(256))
13839 return false;
13840 if (N1->getOpcode() == ISD::ADD && Const->getAPIntValue().slt(0) &&
13841 Const->getAPIntValue().sgt(-256))
13842 return false;
13843 }
13844 return true;
13845 }
13846
13847 // Turn off commute-with-shift transform after legalization, so it doesn't
13848 // conflict with PerformSHLSimplify. (We could try to detect when
13849 // PerformSHLSimplify would trigger more precisely, but it isn't
13850 // really necessary.)
13851 return false;
13852}
13853
13855 const SDNode *N) const {
13856 assert(N->getOpcode() == ISD::XOR &&
13857 (N->getOperand(0).getOpcode() == ISD::SHL ||
13858 N->getOperand(0).getOpcode() == ISD::SRL) &&
13859 "Expected XOR(SHIFT) pattern");
13860
13861 // Only commute if the entire NOT mask is a hidden shifted mask.
13862 auto *XorC = dyn_cast<ConstantSDNode>(N->getOperand(1));
13863 auto *ShiftC = dyn_cast<ConstantSDNode>(N->getOperand(0).getOperand(1));
13864 if (XorC && ShiftC) {
13865 unsigned MaskIdx, MaskLen;
13866 if (XorC->getAPIntValue().isShiftedMask(MaskIdx, MaskLen)) {
13867 unsigned ShiftAmt = ShiftC->getZExtValue();
13868 unsigned BitWidth = N->getValueType(0).getScalarSizeInBits();
13869 if (N->getOperand(0).getOpcode() == ISD::SHL)
13870 return MaskIdx == ShiftAmt && MaskLen == (BitWidth - ShiftAmt);
13871 return MaskIdx == 0 && MaskLen == (BitWidth - ShiftAmt);
13872 }
13873 }
13874
13875 return false;
13876}
13877
13879 const SDNode *N) const {
13880 assert(((N->getOpcode() == ISD::SHL &&
13881 N->getOperand(0).getOpcode() == ISD::SRL) ||
13882 (N->getOpcode() == ISD::SRL &&
13883 N->getOperand(0).getOpcode() == ISD::SHL)) &&
13884 "Expected shift-shift mask");
13885
13886 if (!Subtarget->isThumb1Only())
13887 return true;
13888
13889 EVT VT = N->getValueType(0);
13890 if (VT.getScalarSizeInBits() > 32)
13891 return true;
13892
13893 return false;
13894}
13895
13897 unsigned BinOpcode, EVT VT, unsigned SelectOpcode, SDValue X,
13898 SDValue Y) const {
13899 return Subtarget->hasMVEIntegerOps() && isTypeLegal(VT) &&
13900 SelectOpcode == ISD::VSELECT;
13901}
13902
13904 if (!Subtarget->hasNEON() && !Subtarget->hasMVEIntegerOps()) {
13905 if (Subtarget->isThumb1Only())
13906 return VT.getScalarSizeInBits() <= 32;
13907 return true;
13908 }
13909 return VT.isScalarInteger();
13910}
13911
13913 EVT VT) const {
13914 if (!isOperationLegalOrCustom(Op, VT) || !FPVT.isSimple())
13915 return false;
13916
13917 switch (FPVT.getSimpleVT().SimpleTy) {
13918 case MVT::f16:
13919 return Subtarget->hasVFP2Base();
13920 case MVT::f32:
13921 return Subtarget->hasVFP2Base();
13922 case MVT::f64:
13923 return Subtarget->hasFP64();
13924 case MVT::v4f32:
13925 case MVT::v8f16:
13926 return Subtarget->hasMVEFloatOps();
13927 default:
13928 return false;
13929 }
13930}
13931
13934 const ARMSubtarget *ST) {
13935 // Allow the generic combiner to identify potential bswaps.
13936 if (DCI.isBeforeLegalize())
13937 return SDValue();
13938
13939 // DAG combiner will fold:
13940 // (shl (add x, c1), c2) -> (add (shl x, c2), c1 << c2)
13941 // (shl (or x, c1), c2) -> (or (shl x, c2), c1 << c2
13942 // Other code patterns that can be also be modified have the following form:
13943 // b + ((a << 1) | 510)
13944 // b + ((a << 1) & 510)
13945 // b + ((a << 1) ^ 510)
13946 // b + ((a << 1) + 510)
13947
13948 // Many instructions can perform the shift for free, but it requires both
13949 // the operands to be registers. If c1 << c2 is too large, a mov immediate
13950 // instruction will needed. So, unfold back to the original pattern if:
13951 // - if c1 and c2 are small enough that they don't require mov imms.
13952 // - the user(s) of the node can perform an shl
13953
13954 // No shifted operands for 16-bit instructions.
13955 if (ST->isThumb1Only())
13956 return SDValue();
13957
13958 // Check that all the users could perform the shl themselves.
13959 for (auto *U : N->users()) {
13960 switch(U->getOpcode()) {
13961 default:
13962 return SDValue();
13963 case ISD::SUB:
13964 case ISD::ADD:
13965 case ISD::AND:
13966 case ISD::OR:
13967 case ISD::XOR:
13968 case ISD::SETCC:
13969 case ARMISD::CMP:
13970 // Check that the user isn't already using a constant because there
13971 // aren't any instructions that support an immediate operand and a
13972 // shifted operand.
13973 if (isa<ConstantSDNode>(U->getOperand(0)) ||
13974 isa<ConstantSDNode>(U->getOperand(1)))
13975 return SDValue();
13976
13977 // Check that it's not already using a shift.
13978 if (U->getOperand(0).getOpcode() == ISD::SHL ||
13979 U->getOperand(1).getOpcode() == ISD::SHL)
13980 return SDValue();
13981 break;
13982 }
13983 }
13984
13985 if (N->getOpcode() != ISD::ADD && N->getOpcode() != ISD::OR &&
13986 N->getOpcode() != ISD::XOR && N->getOpcode() != ISD::AND)
13987 return SDValue();
13988
13989 if (N->getOperand(0).getOpcode() != ISD::SHL)
13990 return SDValue();
13991
13992 SDValue SHL = N->getOperand(0);
13993
13994 auto *C1ShlC2 = dyn_cast<ConstantSDNode>(N->getOperand(1));
13995 auto *C2 = dyn_cast<ConstantSDNode>(SHL.getOperand(1));
13996 if (!C1ShlC2 || !C2)
13997 return SDValue();
13998
13999 APInt C2Int = C2->getAPIntValue();
14000 APInt C1Int = C1ShlC2->getAPIntValue();
14001 unsigned C2Width = C2Int.getBitWidth();
14002 if (C2Int.uge(C2Width))
14003 return SDValue();
14004 uint64_t C2Value = C2Int.getZExtValue();
14005
14006 // Check that performing a lshr will not lose any information.
14007 APInt Mask = APInt::getHighBitsSet(C2Width, C2Width - C2Value);
14008 if ((C1Int & Mask) != C1Int)
14009 return SDValue();
14010
14011 // Shift the first constant.
14012 C1Int.lshrInPlace(C2Int);
14013
14014 // The immediates are encoded as an 8-bit value that can be rotated.
14015 auto LargeImm = [](const APInt &Imm) {
14016 unsigned Zeros = Imm.countl_zero() + Imm.countr_zero();
14017 return Imm.getBitWidth() - Zeros > 8;
14018 };
14019
14020 if (LargeImm(C1Int) || LargeImm(C2Int))
14021 return SDValue();
14022
14023 SelectionDAG &DAG = DCI.DAG;
14024 SDLoc dl(N);
14025 SDValue X = SHL.getOperand(0);
14026 SDValue BinOp = DAG.getNode(N->getOpcode(), dl, MVT::i32, X,
14027 DAG.getConstant(C1Int, dl, MVT::i32));
14028 // Shift left to compensate for the lshr of C1Int.
14029 SDValue Res = DAG.getNode(ISD::SHL, dl, MVT::i32, BinOp, SHL.getOperand(1));
14030
14031 LLVM_DEBUG(dbgs() << "Simplify shl use:\n"; SHL.getOperand(0).dump();
14032 SHL.dump(); N->dump());
14033 LLVM_DEBUG(dbgs() << "Into:\n"; X.dump(); BinOp.dump(); Res.dump());
14034 return Res;
14035}
14036
14037
14038/// PerformADDCombine - Target-specific dag combine xforms for ISD::ADD.
14039///
14042 const ARMSubtarget *Subtarget) {
14043 SDValue N0 = N->getOperand(0);
14044 SDValue N1 = N->getOperand(1);
14045
14046 // Only works one way, because it needs an immediate operand.
14047 if (SDValue Result = PerformSHLSimplify(N, DCI, Subtarget))
14048 return Result;
14049
14050 if (SDValue Result = PerformADDVecReduce(N, DCI.DAG, Subtarget))
14051 return Result;
14052
14053 // First try with the default operand order.
14054 if (SDValue Result = PerformADDCombineWithOperands(N, N0, N1, DCI, Subtarget))
14055 return Result;
14056
14057 // If that didn't work, try again with the operands commuted.
14058 return PerformADDCombineWithOperands(N, N1, N0, DCI, Subtarget);
14059}
14060
14061// Combine (sub 0, (csinc X, Y, CC)) -> (csinv -X, Y, CC)
14062// providing -X is as cheap as X (currently, just a constant).
14064 if (N->getValueType(0) != MVT::i32 || !isNullConstant(N->getOperand(0)))
14065 return SDValue();
14066 SDValue CSINC = N->getOperand(1);
14067 if (CSINC.getOpcode() != ARMISD::CSINC || !CSINC.hasOneUse())
14068 return SDValue();
14069
14071 if (!X)
14072 return SDValue();
14073
14074 return DAG.getNode(ARMISD::CSINV, SDLoc(N), MVT::i32,
14075 DAG.getNode(ISD::SUB, SDLoc(N), MVT::i32, N->getOperand(0),
14076 CSINC.getOperand(0)),
14077 CSINC.getOperand(1), CSINC.getOperand(2),
14078 CSINC.getOperand(3));
14079}
14080
14082 // Free to negate.
14084 return 0;
14085
14086 // Will save one instruction.
14087 if (Op.getOpcode() == ISD::SUB && isNullConstant(Op.getOperand(0)))
14088 return -1;
14089
14090 // Can freely negate by converting sra <-> srl.
14091 if (Op.getOpcode() == ISD::SRA || Op.getOpcode() == ISD::SRL) {
14092 ConstantSDNode *ShiftAmt = dyn_cast<ConstantSDNode>(Op.getOperand(1));
14093 if (Op.hasOneUse() && ShiftAmt &&
14094 ShiftAmt->getZExtValue() == Op.getValueType().getScalarSizeInBits() - 1)
14095 return 0;
14096 }
14097
14098 // Will have to create sub.
14099 return 1;
14100}
14101
14102// Try to fold
14103//
14104// (neg (cmov X, Y)) -> (cmov (neg X), (neg Y))
14105//
14106// The folding helps cmov to be matched with csneg without generating
14107// redundant neg instruction.
14109 assert(N->getOpcode() == ISD::SUB);
14110 if (!isNullConstant(N->getOperand(0)))
14111 return SDValue();
14112
14113 SDValue CMov = N->getOperand(1);
14114 if (CMov.getOpcode() != ARMISD::CMOV || !CMov->hasOneUse())
14115 return SDValue();
14116
14117 SDValue N0 = CMov.getOperand(0);
14118 SDValue N1 = CMov.getOperand(1);
14119
14120 // Only perform the fold if we actually save something.
14121 if (getNegationCost(N0) + getNegationCost(N1) > 0)
14122 return SDValue();
14123
14124 SDLoc DL(N);
14125 EVT VT = CMov.getValueType();
14126
14127 SDValue N0N = DAG.getNegative(N0, DL, VT);
14128 SDValue N1N = DAG.getNegative(N1, DL, VT);
14129 return DAG.getNode(ARMISD::CMOV, DL, VT, N0N, N1N, CMov.getOperand(2),
14130 CMov.getOperand(3));
14131}
14132
14133/// PerformSUBCombine - Target-specific dag combine xforms for ISD::SUB.
14134///
14137 const ARMSubtarget *Subtarget) {
14138 SDValue N0 = N->getOperand(0);
14139 SDValue N1 = N->getOperand(1);
14140
14141 // fold (sub x, (select cc, 0, c)) -> (select cc, x, (sub, x, c))
14142 if (N1.getNode()->hasOneUse())
14143 if (SDValue Result = combineSelectAndUse(N, N1, N0, DCI))
14144 return Result;
14145
14146 if (SDValue R = PerformSubCSINCCombine(N, DCI.DAG))
14147 return R;
14148
14149 if (SDValue Val = performNegCMovCombine(N, DCI.DAG))
14150 return Val;
14151
14152 if (!Subtarget->hasMVEIntegerOps() || !N->getValueType(0).isVector())
14153 return SDValue();
14154
14155 // Fold (sub (ARMvmovImm 0), (ARMvdup x)) -> (ARMvdup (sub 0, x))
14156 // so that we can readily pattern match more mve instructions which can use
14157 // a scalar operand.
14158 SDValue VDup = N->getOperand(1);
14159 if (VDup->getOpcode() != ARMISD::VDUP)
14160 return SDValue();
14161
14162 SDValue VMov = N->getOperand(0);
14163 if (VMov->getOpcode() == ISD::BITCAST)
14164 VMov = VMov->getOperand(0);
14165
14166 if (VMov->getOpcode() != ARMISD::VMOVIMM || !isZeroVector(VMov))
14167 return SDValue();
14168
14169 SDLoc dl(N);
14170 SDValue Negate = DCI.DAG.getNode(ISD::SUB, dl, MVT::i32,
14171 DCI.DAG.getConstant(0, dl, MVT::i32),
14172 VDup->getOperand(0));
14173 return DCI.DAG.getNode(ARMISD::VDUP, dl, N->getValueType(0), Negate);
14174}
14175
14176/// PerformVMULCombine
14177/// Distribute (A + B) * C to (A * C) + (B * C) to take advantage of the
14178/// special multiplier accumulator forwarding.
14179/// vmul d3, d0, d2
14180/// vmla d3, d1, d2
14181/// is faster than
14182/// vadd d3, d0, d1
14183/// vmul d3, d3, d2
14184// However, for (A + B) * (A + B),
14185// vadd d2, d0, d1
14186// vmul d3, d0, d2
14187// vmla d3, d1, d2
14188// is slower than
14189// vadd d2, d0, d1
14190// vmul d3, d2, d2
14193 const ARMSubtarget *Subtarget) {
14194 if (!Subtarget->hasVMLxForwarding())
14195 return SDValue();
14196
14197 SelectionDAG &DAG = DCI.DAG;
14198 SDValue N0 = N->getOperand(0);
14199 SDValue N1 = N->getOperand(1);
14200 unsigned Opcode = N0.getOpcode();
14201 if (Opcode != ISD::ADD && Opcode != ISD::SUB &&
14202 Opcode != ISD::FADD && Opcode != ISD::FSUB) {
14203 Opcode = N1.getOpcode();
14204 if (Opcode != ISD::ADD && Opcode != ISD::SUB &&
14205 Opcode != ISD::FADD && Opcode != ISD::FSUB)
14206 return SDValue();
14207 std::swap(N0, N1);
14208 }
14209
14210 if (N0 == N1)
14211 return SDValue();
14212
14213 EVT VT = N->getValueType(0);
14214 SDLoc DL(N);
14215 SDValue N00 = N0->getOperand(0);
14216 SDValue N01 = N0->getOperand(1);
14217 return DAG.getNode(Opcode, DL, VT,
14218 DAG.getNode(ISD::MUL, DL, VT, N00, N1),
14219 DAG.getNode(ISD::MUL, DL, VT, N01, N1));
14220}
14221
14223 const ARMSubtarget *Subtarget) {
14224 EVT VT = N->getValueType(0);
14225 if (VT != MVT::v2i64)
14226 return SDValue();
14227
14228 SDValue N0 = N->getOperand(0);
14229 SDValue N1 = N->getOperand(1);
14230
14231 auto IsSignExt = [&](SDValue Op) {
14232 if (Op->getOpcode() != ISD::SIGN_EXTEND_INREG)
14233 return SDValue();
14234 EVT VT = cast<VTSDNode>(Op->getOperand(1))->getVT();
14235 if (VT.getScalarSizeInBits() == 32)
14236 return Op->getOperand(0);
14237 return SDValue();
14238 };
14239 auto IsZeroExt = [&](SDValue Op) {
14240 // Zero extends are a little more awkward. At the point we are matching
14241 // this, we are looking for an AND with a (-1, 0, -1, 0) buildvector mask.
14242 // That might be before of after a bitcast depending on how the and is
14243 // placed. Because this has to look through bitcasts, it is currently only
14244 // supported on LE.
14245 if (!Subtarget->isLittle())
14246 return SDValue();
14247
14248 SDValue And = Op;
14249 if (And->getOpcode() == ISD::BITCAST)
14250 And = And->getOperand(0);
14251 if (And->getOpcode() != ISD::AND)
14252 return SDValue();
14253 SDValue Mask = And->getOperand(1);
14254 if (Mask->getOpcode() == ISD::BITCAST)
14255 Mask = Mask->getOperand(0);
14256
14257 if (Mask->getOpcode() != ISD::BUILD_VECTOR ||
14258 Mask.getValueType() != MVT::v4i32)
14259 return SDValue();
14260 if (isAllOnesConstant(Mask->getOperand(0)) &&
14261 isNullConstant(Mask->getOperand(1)) &&
14262 isAllOnesConstant(Mask->getOperand(2)) &&
14263 isNullConstant(Mask->getOperand(3)))
14264 return And->getOperand(0);
14265 return SDValue();
14266 };
14267
14268 SDLoc dl(N);
14269 if (SDValue Op0 = IsSignExt(N0)) {
14270 if (SDValue Op1 = IsSignExt(N1)) {
14271 SDValue New0a = DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, MVT::v4i32, Op0);
14272 SDValue New1a = DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, MVT::v4i32, Op1);
14273 return DAG.getNode(ARMISD::VMULLs, dl, VT, New0a, New1a);
14274 }
14275 }
14276 if (SDValue Op0 = IsZeroExt(N0)) {
14277 if (SDValue Op1 = IsZeroExt(N1)) {
14278 SDValue New0a = DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, MVT::v4i32, Op0);
14279 SDValue New1a = DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, MVT::v4i32, Op1);
14280 return DAG.getNode(ARMISD::VMULLu, dl, VT, New0a, New1a);
14281 }
14282 }
14283
14284 return SDValue();
14285}
14286
14289 const ARMSubtarget *Subtarget) {
14290 SelectionDAG &DAG = DCI.DAG;
14291
14292 EVT VT = N->getValueType(0);
14293 if (Subtarget->hasMVEIntegerOps() && VT == MVT::v2i64)
14294 return PerformMVEVMULLCombine(N, DAG, Subtarget);
14295
14296 if (Subtarget->isThumb1Only())
14297 return SDValue();
14298
14299 if (DCI.isBeforeLegalize() || DCI.isCalledByLegalizer())
14300 return SDValue();
14301
14302 if (VT.is64BitVector() || VT.is128BitVector())
14303 return PerformVMULCombine(N, DCI, Subtarget);
14304 if (VT != MVT::i32)
14305 return SDValue();
14306
14307 ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(1));
14308 if (!C)
14309 return SDValue();
14310
14311 int64_t MulAmt = C->getSExtValue();
14312 unsigned ShiftAmt = llvm::countr_zero<uint64_t>(MulAmt);
14313
14314 ShiftAmt = ShiftAmt & (32 - 1);
14315 SDValue V = N->getOperand(0);
14316 SDLoc DL(N);
14317
14318 SDValue Res;
14319 MulAmt >>= ShiftAmt;
14320
14321 if (MulAmt >= 0) {
14322 if (llvm::has_single_bit<uint32_t>(MulAmt - 1)) {
14323 // (mul x, 2^N + 1) => (add (shl x, N), x)
14324 Res = DAG.getNode(ISD::ADD, DL, VT,
14325 V,
14326 DAG.getNode(ISD::SHL, DL, VT,
14327 V,
14328 DAG.getConstant(Log2_32(MulAmt - 1), DL,
14329 MVT::i32)));
14330 } else if (llvm::has_single_bit<uint32_t>(MulAmt + 1)) {
14331 // (mul x, 2^N - 1) => (sub (shl x, N), x)
14332 Res = DAG.getNode(ISD::SUB, DL, VT,
14333 DAG.getNode(ISD::SHL, DL, VT,
14334 V,
14335 DAG.getConstant(Log2_32(MulAmt + 1), DL,
14336 MVT::i32)),
14337 V);
14338 } else
14339 return SDValue();
14340 } else {
14341 uint64_t MulAmtAbs = -MulAmt;
14342 if (llvm::has_single_bit<uint32_t>(MulAmtAbs + 1)) {
14343 // (mul x, -(2^N - 1)) => (sub x, (shl x, N))
14344 Res = DAG.getNode(ISD::SUB, DL, VT,
14345 V,
14346 DAG.getNode(ISD::SHL, DL, VT,
14347 V,
14348 DAG.getConstant(Log2_32(MulAmtAbs + 1), DL,
14349 MVT::i32)));
14350 } else if (llvm::has_single_bit<uint32_t>(MulAmtAbs - 1)) {
14351 // (mul x, -(2^N + 1)) => - (add (shl x, N), x)
14352 Res = DAG.getNode(ISD::ADD, DL, VT,
14353 V,
14354 DAG.getNode(ISD::SHL, DL, VT,
14355 V,
14356 DAG.getConstant(Log2_32(MulAmtAbs - 1), DL,
14357 MVT::i32)));
14358 Res = DAG.getNode(ISD::SUB, DL, VT,
14359 DAG.getConstant(0, DL, MVT::i32), Res);
14360 } else
14361 return SDValue();
14362 }
14363
14364 if (ShiftAmt != 0)
14365 Res = DAG.getNode(ISD::SHL, DL, VT,
14366 Res, DAG.getConstant(ShiftAmt, DL, MVT::i32));
14367
14368 // Do not add new nodes to DAG combiner worklist.
14369 DCI.CombineTo(N, Res, false);
14370 return SDValue();
14371}
14372
14375 const ARMSubtarget *Subtarget) {
14376 // Allow DAGCombine to pattern-match before we touch the canonical form.
14377 if (DCI.isBeforeLegalize() || DCI.isCalledByLegalizer())
14378 return SDValue();
14379
14380 if (N->getValueType(0) != MVT::i32)
14381 return SDValue();
14382
14383 ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N->getOperand(1));
14384 if (!N1C)
14385 return SDValue();
14386
14387 uint32_t C1 = (uint32_t)N1C->getZExtValue();
14388 // Don't transform uxtb/uxth.
14389 if (C1 == 255 || C1 == 65535)
14390 return SDValue();
14391
14392 SDNode *N0 = N->getOperand(0).getNode();
14393 if (!N0->hasOneUse())
14394 return SDValue();
14395
14396 if (N0->getOpcode() != ISD::SHL && N0->getOpcode() != ISD::SRL)
14397 return SDValue();
14398
14399 bool LeftShift = N0->getOpcode() == ISD::SHL;
14400
14402 if (!N01C)
14403 return SDValue();
14404
14405 uint32_t C2 = (uint32_t)N01C->getZExtValue();
14406 if (!C2 || C2 >= 32)
14407 return SDValue();
14408
14409 // Clear irrelevant bits in the mask.
14410 if (LeftShift)
14411 C1 &= (-1U << C2);
14412 else
14413 C1 &= (-1U >> C2);
14414
14415 SelectionDAG &DAG = DCI.DAG;
14416 SDLoc DL(N);
14417
14418 // We have a pattern of the form "(and (shl x, c2) c1)" or
14419 // "(and (srl x, c2) c1)", where c1 is a shifted mask. Try to
14420 // transform to a pair of shifts, to save materializing c1.
14421
14422 // First pattern: right shift, then mask off leading bits.
14423 // FIXME: Use demanded bits?
14424 if (!LeftShift && isMask_32(C1)) {
14425 uint32_t C3 = llvm::countl_zero(C1);
14426 if (C2 < C3) {
14427 SDValue SHL = DAG.getNode(ISD::SHL, DL, MVT::i32, N0->getOperand(0),
14428 DAG.getConstant(C3 - C2, DL, MVT::i32));
14429 return DAG.getNode(ISD::SRL, DL, MVT::i32, SHL,
14430 DAG.getConstant(C3, DL, MVT::i32));
14431 }
14432 }
14433
14434 // First pattern, reversed: left shift, then mask off trailing bits.
14435 if (LeftShift && isMask_32(~C1)) {
14436 uint32_t C3 = llvm::countr_zero(C1);
14437 if (C2 < C3) {
14438 SDValue SHL = DAG.getNode(ISD::SRL, DL, MVT::i32, N0->getOperand(0),
14439 DAG.getConstant(C3 - C2, DL, MVT::i32));
14440 return DAG.getNode(ISD::SHL, DL, MVT::i32, SHL,
14441 DAG.getConstant(C3, DL, MVT::i32));
14442 }
14443 }
14444
14445 // Second pattern: left shift, then mask off leading bits.
14446 // FIXME: Use demanded bits?
14447 if (LeftShift && isShiftedMask_32(C1)) {
14448 uint32_t Trailing = llvm::countr_zero(C1);
14449 uint32_t C3 = llvm::countl_zero(C1);
14450 if (Trailing == C2 && C2 + C3 < 32) {
14451 SDValue SHL = DAG.getNode(ISD::SHL, DL, MVT::i32, N0->getOperand(0),
14452 DAG.getConstant(C2 + C3, DL, MVT::i32));
14453 return DAG.getNode(ISD::SRL, DL, MVT::i32, SHL,
14454 DAG.getConstant(C3, DL, MVT::i32));
14455 }
14456 }
14457
14458 // Second pattern, reversed: right shift, then mask off trailing bits.
14459 // FIXME: Handle other patterns of known/demanded bits.
14460 if (!LeftShift && isShiftedMask_32(C1)) {
14461 uint32_t Leading = llvm::countl_zero(C1);
14462 uint32_t C3 = llvm::countr_zero(C1);
14463 if (Leading == C2 && C2 + C3 < 32) {
14464 SDValue SHL = DAG.getNode(ISD::SRL, DL, MVT::i32, N0->getOperand(0),
14465 DAG.getConstant(C2 + C3, DL, MVT::i32));
14466 return DAG.getNode(ISD::SHL, DL, MVT::i32, SHL,
14467 DAG.getConstant(C3, DL, MVT::i32));
14468 }
14469 }
14470
14471 // Transform "(and (shl x, c2) c1)" into "(shl (and x, c1>>c2), c2)"
14472 // if "c1 >> c2" is a cheaper immediate than "c1"
14473 if (LeftShift &&
14474 HasLowerConstantMaterializationCost(C1 >> C2, C1, Subtarget)) {
14475
14476 SDValue And = DAG.getNode(ISD::AND, DL, MVT::i32, N0->getOperand(0),
14477 DAG.getConstant(C1 >> C2, DL, MVT::i32));
14478 return DAG.getNode(ISD::SHL, DL, MVT::i32, And,
14479 DAG.getConstant(C2, DL, MVT::i32));
14480 }
14481
14482 return SDValue();
14483}
14484
14487 const ARMSubtarget *Subtarget) {
14488 // Attempt to use immediate-form VBIC
14489 BuildVectorSDNode *BVN = dyn_cast<BuildVectorSDNode>(N->getOperand(1));
14490 SDLoc dl(N);
14491 EVT VT = N->getValueType(0);
14492 SelectionDAG &DAG = DCI.DAG;
14493
14494 if (!DAG.getTargetLoweringInfo().isTypeLegal(VT) || VT == MVT::v2i1 ||
14495 VT == MVT::v4i1 || VT == MVT::v8i1 || VT == MVT::v16i1)
14496 return SDValue();
14497
14498 APInt SplatBits, SplatUndef;
14499 unsigned SplatBitSize;
14500 bool HasAnyUndefs;
14501 if (BVN && (Subtarget->hasNEON() || Subtarget->hasMVEIntegerOps()) &&
14502 BVN->isConstantSplat(SplatBits, SplatUndef, SplatBitSize, HasAnyUndefs)) {
14503 if (SplatBitSize == 8 || SplatBitSize == 16 || SplatBitSize == 32 ||
14504 SplatBitSize == 64) {
14505 EVT VbicVT;
14506 SDValue Val = isVMOVModifiedImm((~SplatBits).getZExtValue(),
14507 SplatUndef.getZExtValue(), SplatBitSize,
14508 DAG, dl, VbicVT, VT, OtherModImm);
14509 if (Val.getNode()) {
14510 SDValue Input =
14511 DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, VbicVT, N->getOperand(0));
14512 SDValue Vbic = DAG.getNode(ARMISD::VBICIMM, dl, VbicVT, Input, Val);
14513 return DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, VT, Vbic);
14514 }
14515 }
14516 }
14517
14518 if (!Subtarget->isThumb1Only()) {
14519 // fold (and (select cc, -1, c), x) -> (select cc, x, (and, x, c))
14520 if (SDValue Result = combineSelectAndUseCommutative(N, true, DCI))
14521 return Result;
14522
14523 if (SDValue Result = PerformSHLSimplify(N, DCI, Subtarget))
14524 return Result;
14525 }
14526
14527 if (Subtarget->isThumb1Only())
14528 if (SDValue Result = CombineANDShift(N, DCI, Subtarget))
14529 return Result;
14530
14531 return SDValue();
14532}
14533
14534// Try combining OR nodes to SMULWB, SMULWT.
14537 const ARMSubtarget *Subtarget) {
14538 if (!Subtarget->hasV6Ops() ||
14539 (Subtarget->isThumb() &&
14540 (!Subtarget->hasThumb2() || !Subtarget->hasDSP())))
14541 return SDValue();
14542
14543 SDValue SRL = OR->getOperand(0);
14544 SDValue SHL = OR->getOperand(1);
14545
14546 if (SRL.getOpcode() != ISD::SRL || SHL.getOpcode() != ISD::SHL) {
14547 SRL = OR->getOperand(1);
14548 SHL = OR->getOperand(0);
14549 }
14550 if (!isSRL16(SRL) || !isSHL16(SHL))
14551 return SDValue();
14552
14553 // The first operands to the shifts need to be the two results from the
14554 // same smul_lohi node.
14555 if ((SRL.getOperand(0).getNode() != SHL.getOperand(0).getNode()) ||
14556 SRL.getOperand(0).getOpcode() != ISD::SMUL_LOHI)
14557 return SDValue();
14558
14559 SDNode *SMULLOHI = SRL.getOperand(0).getNode();
14560 if (SRL.getOperand(0) != SDValue(SMULLOHI, 0) ||
14561 SHL.getOperand(0) != SDValue(SMULLOHI, 1))
14562 return SDValue();
14563
14564 // Now we have:
14565 // (or (srl (smul_lohi ?, ?), 16), (shl (smul_lohi ?, ?), 16)))
14566 // For SMUL[B|T] smul_lohi will take a 32-bit and a 16-bit arguments.
14567 // For SMUWB the 16-bit value will signed extended somehow.
14568 // For SMULWT only the SRA is required.
14569 // Check both sides of SMUL_LOHI
14570 SDValue OpS16 = SMULLOHI->getOperand(0);
14571 SDValue OpS32 = SMULLOHI->getOperand(1);
14572
14573 SelectionDAG &DAG = DCI.DAG;
14574 if (!isS16(OpS16, DAG) && !isSRA16(OpS16)) {
14575 OpS16 = OpS32;
14576 OpS32 = SMULLOHI->getOperand(0);
14577 }
14578
14579 SDLoc dl(OR);
14580 unsigned Opcode = 0;
14581 if (isS16(OpS16, DAG))
14582 Opcode = ARMISD::SMULWB;
14583 else if (isSRA16(OpS16)) {
14584 Opcode = ARMISD::SMULWT;
14585 OpS16 = OpS16->getOperand(0);
14586 }
14587 else
14588 return SDValue();
14589
14590 SDValue Res = DAG.getNode(Opcode, dl, MVT::i32, OpS32, OpS16);
14591 DAG.ReplaceAllUsesOfValueWith(SDValue(OR, 0), Res);
14592 return SDValue(OR, 0);
14593}
14594
14597 const ARMSubtarget *Subtarget) {
14598 // BFI is only available on V6T2+
14599 if (Subtarget->isThumb1Only() || !Subtarget->hasV6T2Ops())
14600 return SDValue();
14601
14602 EVT VT = N->getValueType(0);
14603 SDValue N0 = N->getOperand(0);
14604 SDValue N1 = N->getOperand(1);
14605 SelectionDAG &DAG = DCI.DAG;
14606 SDLoc DL(N);
14607 // 1) or (and A, mask), val => ARMbfi A, val, mask
14608 // iff (val & mask) == val
14609 //
14610 // 2) or (and A, mask), (and B, mask2) => ARMbfi A, (lsr B, amt), mask
14611 // 2a) iff isBitFieldInvertedMask(mask) && isBitFieldInvertedMask(~mask2)
14612 // && mask == ~mask2
14613 // 2b) iff isBitFieldInvertedMask(~mask) && isBitFieldInvertedMask(mask2)
14614 // && ~mask == mask2
14615 // (i.e., copy a bitfield value into another bitfield of the same width)
14616
14617 if (VT != MVT::i32)
14618 return SDValue();
14619
14620 SDValue N00 = N0.getOperand(0);
14621
14622 // The value and the mask need to be constants so we can verify this is
14623 // actually a bitfield set. If the mask is 0xffff, we can do better
14624 // via a movt instruction, so don't use BFI in that case.
14625 SDValue MaskOp = N0.getOperand(1);
14627 if (!MaskC)
14628 return SDValue();
14629 unsigned Mask = MaskC->getZExtValue();
14630 if (Mask == 0xffff)
14631 return SDValue();
14632 SDValue Res;
14633 // Case (1): or (and A, mask), val => ARMbfi A, val, mask
14635 if (N1C) {
14636 unsigned Val = N1C->getZExtValue();
14637 if ((Val & ~Mask) != Val)
14638 return SDValue();
14639
14640 if (ARM::isBitFieldInvertedMask(Mask)) {
14641 Val >>= llvm::countr_zero(~Mask);
14642
14643 Res = DAG.getNode(ARMISD::BFI, DL, VT, N00,
14644 DAG.getConstant(Val, DL, MVT::i32),
14645 DAG.getConstant(Mask, DL, MVT::i32));
14646
14647 DCI.CombineTo(N, Res, false);
14648 // Return value from the original node to inform the combiner than N is
14649 // now dead.
14650 return SDValue(N, 0);
14651 }
14652 } else if (N1.getOpcode() == ISD::AND) {
14653 // case (2) or (and A, mask), (and B, mask2) => ARMbfi A, (lsr B, amt), mask
14655 if (!N11C)
14656 return SDValue();
14657 unsigned Mask2 = N11C->getZExtValue();
14658
14659 // Mask and ~Mask2 (or reverse) must be equivalent for the BFI pattern
14660 // as is to match.
14661 if (ARM::isBitFieldInvertedMask(Mask) &&
14662 (Mask == ~Mask2)) {
14663 // The pack halfword instruction works better for masks that fit it,
14664 // so use that when it's available.
14665 if (Subtarget->hasDSP() &&
14666 (Mask == 0xffff || Mask == 0xffff0000))
14667 return SDValue();
14668 // 2a
14669 unsigned amt = llvm::countr_zero(Mask2);
14670 Res = DAG.getNode(ISD::SRL, DL, VT, N1.getOperand(0),
14671 DAG.getConstant(amt, DL, MVT::i32));
14672 Res = DAG.getNode(ARMISD::BFI, DL, VT, N00, Res,
14673 DAG.getConstant(Mask, DL, MVT::i32));
14674 DCI.CombineTo(N, Res, false);
14675 // Return value from the original node to inform the combiner than N is
14676 // now dead.
14677 return SDValue(N, 0);
14678 } else if (ARM::isBitFieldInvertedMask(~Mask) &&
14679 (~Mask == Mask2)) {
14680 // The pack halfword instruction works better for masks that fit it,
14681 // so use that when it's available.
14682 if (Subtarget->hasDSP() &&
14683 (Mask2 == 0xffff || Mask2 == 0xffff0000))
14684 return SDValue();
14685 // 2b
14686 unsigned lsb = llvm::countr_zero(Mask);
14687 Res = DAG.getNode(ISD::SRL, DL, VT, N00,
14688 DAG.getConstant(lsb, DL, MVT::i32));
14689 Res = DAG.getNode(ARMISD::BFI, DL, VT, N1.getOperand(0), Res,
14690 DAG.getConstant(Mask2, DL, MVT::i32));
14691 DCI.CombineTo(N, Res, false);
14692 // Return value from the original node to inform the combiner than N is
14693 // now dead.
14694 return SDValue(N, 0);
14695 }
14696 }
14697
14698 if (DAG.MaskedValueIsZero(N1, MaskC->getAPIntValue()) &&
14699 N00.getOpcode() == ISD::SHL && isa<ConstantSDNode>(N00.getOperand(1)) &&
14701 // Case (3): or (and (shl A, #shamt), mask), B => ARMbfi B, A, ~mask
14702 // where lsb(mask) == #shamt and masked bits of B are known zero.
14703 SDValue ShAmt = N00.getOperand(1);
14704 unsigned ShAmtC = ShAmt->getAsZExtVal();
14705 unsigned LSB = llvm::countr_zero(Mask);
14706 if (ShAmtC != LSB)
14707 return SDValue();
14708
14709 Res = DAG.getNode(ARMISD::BFI, DL, VT, N1, N00.getOperand(0),
14710 DAG.getConstant(~Mask, DL, MVT::i32));
14711
14712 DCI.CombineTo(N, Res, false);
14713 // Return value from the original node to inform the combiner than N is
14714 // now dead.
14715 return SDValue(N, 0);
14716 }
14717
14718 return SDValue();
14719}
14720
14721static bool isValidMVECond(unsigned CC, bool IsFloat) {
14722 switch (CC) {
14723 case ARMCC::EQ:
14724 case ARMCC::NE:
14725 case ARMCC::LE:
14726 case ARMCC::GT:
14727 case ARMCC::GE:
14728 case ARMCC::LT:
14729 return true;
14730 case ARMCC::HS:
14731 case ARMCC::HI:
14732 return !IsFloat;
14733 default:
14734 return false;
14735 };
14736}
14737
14739 if (N->getOpcode() == ARMISD::VCMP)
14740 return (ARMCC::CondCodes)N->getConstantOperandVal(2);
14741 else if (N->getOpcode() == ARMISD::VCMPZ)
14742 return (ARMCC::CondCodes)N->getConstantOperandVal(1);
14743 else
14744 llvm_unreachable("Not a VCMP/VCMPZ!");
14745}
14746
14749 return isValidMVECond(CC, N->getOperand(0).getValueType().isFloatingPoint());
14750}
14751
14753 const ARMSubtarget *Subtarget) {
14754 // Try to invert "or A, B" -> "and ~A, ~B", as the "and" is easier to chain
14755 // together with predicates
14756 EVT VT = N->getValueType(0);
14757 SDLoc DL(N);
14758 SDValue N0 = N->getOperand(0);
14759 SDValue N1 = N->getOperand(1);
14760
14761 auto IsFreelyInvertable = [&](SDValue V) {
14762 if (V->getOpcode() == ARMISD::VCMP || V->getOpcode() == ARMISD::VCMPZ)
14763 return CanInvertMVEVCMP(V);
14764 return false;
14765 };
14766
14767 // At least one operand must be freely invertable.
14768 if (!(IsFreelyInvertable(N0) || IsFreelyInvertable(N1)))
14769 return SDValue();
14770
14771 SDValue NewN0 = DAG.getLogicalNOT(DL, N0, VT);
14772 SDValue NewN1 = DAG.getLogicalNOT(DL, N1, VT);
14773 SDValue And = DAG.getNode(ISD::AND, DL, VT, NewN0, NewN1);
14774 return DAG.getLogicalNOT(DL, And, VT);
14775}
14776
14777// Try to form a NEON shift-{right, left}-and-insert (VSRI/VSLI) from:
14778// (or (and X, splat (i32 C1)), (srl Y, splat (i32 C2))) -> VSRI X, Y, #C2
14779// (or (and X, splat (i32 C1)), (shl Y, splat (i32 C2))) -> VSLI X, Y, #C2
14780// where C1 is a mask that preserves the bits not written by the shift/insert,
14781// i.e. `C1 == (1 << C2) - 1`.
14783 SDValue ShiftOp, EVT VT,
14784 SDLoc dl) {
14785 // Match (and X, Mask)
14786 if (AndOp.getOpcode() != ISD::AND)
14787 return SDValue();
14788
14789 SDValue X = AndOp.getOperand(0);
14790 SDValue Mask = AndOp.getOperand(1);
14791
14792 ConstantSDNode *MaskC = isConstOrConstSplat(Mask, false, true);
14793 if (!MaskC)
14794 return SDValue();
14795 APInt MaskBits =
14796 MaskC->getAPIntValue().trunc(Mask.getScalarValueSizeInBits());
14797
14798 // Match shift (srl/shl Y, CntVec)
14799 int64_t Cnt = 0;
14800 bool IsShiftRight = false;
14801 SDValue Y;
14802
14803 if (ShiftOp.getOpcode() == ARMISD::VSHRuIMM) {
14804 IsShiftRight = true;
14805 Y = ShiftOp.getOperand(0);
14806 Cnt = ShiftOp.getConstantOperandVal(1);
14807 } else if (ShiftOp.getOpcode() == ARMISD::VSHLIMM) {
14808 Y = ShiftOp.getOperand(0);
14809 Cnt = ShiftOp.getConstantOperandVal(1);
14810 } else {
14811 return SDValue();
14812 }
14813
14814 unsigned ElemBits = VT.getScalarSizeInBits();
14815 APInt RequiredMask = IsShiftRight
14816 ? APInt::getHighBitsSet(ElemBits, (unsigned)Cnt)
14817 : APInt::getLowBitsSet(ElemBits, (unsigned)Cnt);
14818 if (MaskBits != RequiredMask)
14819 return SDValue();
14820
14821 unsigned Opc = IsShiftRight ? ARMISD::VSRIIMM : ARMISD::VSLIIMM;
14822 return DAG.getNode(Opc, dl, VT, X, Y, DAG.getConstant(Cnt, dl, MVT::i32));
14823}
14824
14825/// PerformORCombine - Target-specific dag combine xforms for ISD::OR
14827 const ARMSubtarget *Subtarget) {
14828 // Attempt to use immediate-form VORR
14829 BuildVectorSDNode *BVN = dyn_cast<BuildVectorSDNode>(N->getOperand(1));
14830 SDLoc dl(N);
14831 EVT VT = N->getValueType(0);
14832 SelectionDAG &DAG = DCI.DAG;
14833
14834 if (!DAG.getTargetLoweringInfo().isTypeLegal(VT))
14835 return SDValue();
14836
14837 if (Subtarget->hasMVEIntegerOps() && (VT == MVT::v2i1 || VT == MVT::v4i1 ||
14838 VT == MVT::v8i1 || VT == MVT::v16i1))
14839 return PerformORCombine_i1(N, DAG, Subtarget);
14840
14841 APInt SplatBits, SplatUndef;
14842 unsigned SplatBitSize;
14843 bool HasAnyUndefs;
14844 if (BVN && (Subtarget->hasNEON() || Subtarget->hasMVEIntegerOps()) &&
14845 BVN->isConstantSplat(SplatBits, SplatUndef, SplatBitSize, HasAnyUndefs)) {
14846 if (SplatBitSize == 8 || SplatBitSize == 16 || SplatBitSize == 32 ||
14847 SplatBitSize == 64) {
14848 EVT VorrVT;
14849 SDValue Val =
14850 isVMOVModifiedImm(SplatBits.getZExtValue(), SplatUndef.getZExtValue(),
14851 SplatBitSize, DAG, dl, VorrVT, VT, OtherModImm);
14852 if (Val.getNode()) {
14853 SDValue Input =
14854 DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, VorrVT, N->getOperand(0));
14855 SDValue Vorr = DAG.getNode(ARMISD::VORRIMM, dl, VorrVT, Input, Val);
14856 return DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, VT, Vorr);
14857 }
14858 }
14859 }
14860
14861 if (!Subtarget->isThumb1Only()) {
14862 // fold (or (select cc, 0, c), x) -> (select cc, x, (or, x, c))
14863 if (SDValue Result = combineSelectAndUseCommutative(N, false, DCI))
14864 return Result;
14865 if (SDValue Result = PerformORCombineToSMULWBT(N, DCI, Subtarget))
14866 return Result;
14867 }
14868
14869 SDValue N0 = N->getOperand(0);
14870 SDValue N1 = N->getOperand(1);
14871
14872 // (or (and X, C1), (srl Y, C2)) -> VSRI X, Y, #C2
14873 // (or (and X, C1), (shl Y, C2)) -> VSLI X, Y, #C2
14874 if (VT.isVector() &&
14875 ((Subtarget->hasNEON() && DAG.getTargetLoweringInfo().isTypeLegal(VT)) ||
14876 (Subtarget->hasMVEIntegerOps() &&
14877 (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32)))) {
14878 if (SDValue ShiftInsert =
14879 PerformORCombineToShiftInsert(DAG, N0, N1, VT, dl))
14880 return ShiftInsert;
14881
14882 if (SDValue ShiftInsert =
14883 PerformORCombineToShiftInsert(DAG, N1, N0, VT, dl))
14884 return ShiftInsert;
14885 }
14886
14887 // (or (and B, A), (and C, ~A)) => (VBSL A, B, C) when A is a constant.
14888 if (Subtarget->hasNEON() && N1.getOpcode() == ISD::AND && VT.isVector() &&
14890
14891 // The code below optimizes (or (and X, Y), Z).
14892 // The AND operand needs to have a single user to make these optimizations
14893 // profitable.
14894 if (N0.getOpcode() != ISD::AND || !N0.hasOneUse())
14895 return SDValue();
14896
14897 APInt SplatUndef;
14898 unsigned SplatBitSize;
14899 bool HasAnyUndefs;
14900
14901 APInt SplatBits0, SplatBits1;
14904 // Ensure that the second operand of both ands are constants
14905 if (BVN0 && BVN0->isConstantSplat(SplatBits0, SplatUndef, SplatBitSize,
14906 HasAnyUndefs) && !HasAnyUndefs) {
14907 if (BVN1 && BVN1->isConstantSplat(SplatBits1, SplatUndef, SplatBitSize,
14908 HasAnyUndefs) && !HasAnyUndefs) {
14909 // Ensure that the bit width of the constants are the same and that
14910 // the splat arguments are logical inverses as per the pattern we
14911 // are trying to simplify.
14912 if (SplatBits0.getBitWidth() == SplatBits1.getBitWidth() &&
14913 SplatBits0 == ~SplatBits1) {
14914 // Canonicalize the vector type to make instruction selection
14915 // simpler.
14916 EVT CanonicalVT = VT.is128BitVector() ? MVT::v4i32 : MVT::v2i32;
14917 SDValue Result = DAG.getNode(ARMISD::VBSP, dl, CanonicalVT,
14918 N0->getOperand(1),
14919 N0->getOperand(0),
14920 N1->getOperand(0));
14921 return DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, VT, Result);
14922 }
14923 }
14924 }
14925 }
14926
14927 // Try to use the ARM/Thumb2 BFI (bitfield insert) instruction when
14928 // reasonable.
14929 if (N0.getOpcode() == ISD::AND && N0.hasOneUse()) {
14930 if (SDValue Res = PerformORCombineToBFI(N, DCI, Subtarget))
14931 return Res;
14932 }
14933
14934 if (SDValue Result = PerformSHLSimplify(N, DCI, Subtarget))
14935 return Result;
14936
14937 // (or x, (csinc 0, 0, cc)) -> (csinc x, 0, cc)
14938 // providing that the x is 0 or 1.
14939 SDValue CSINC = N1;
14940 SDValue Other = N0;
14941 if (CSINC.getOpcode() != ARMISD::CSINC)
14942 std::swap(CSINC, Other);
14943 if (CSINC.getOpcode() == ARMISD::CSINC &&
14944 isNullConstant(CSINC.getOperand(0)) &&
14945 isNullConstant(CSINC.getOperand(1)) &&
14947 return DAG.getNode(ARMISD::CSINC, dl, VT, Other, CSINC.getOperand(1),
14948 CSINC.getOperand(2), CSINC.getOperand(3));
14949
14950 return SDValue();
14951}
14952
14955 const ARMSubtarget *Subtarget) {
14956 EVT VT = N->getValueType(0);
14957 SelectionDAG &DAG = DCI.DAG;
14958
14959 if(!DAG.getTargetLoweringInfo().isTypeLegal(VT))
14960 return SDValue();
14961
14962 if (!Subtarget->isThumb1Only()) {
14963 // fold (xor (select cc, 0, c), x) -> (select cc, x, (xor, x, c))
14964 if (SDValue Result = combineSelectAndUseCommutative(N, false, DCI))
14965 return Result;
14966
14967 if (SDValue Result = PerformSHLSimplify(N, DCI, Subtarget))
14968 return Result;
14969 }
14970
14971 if (Subtarget->hasMVEIntegerOps()) {
14972 // fold (xor(vcmp/z, 1)) into a vcmp with the opposite condition.
14973 SDValue N0 = N->getOperand(0);
14974 SDValue N1 = N->getOperand(1);
14975 const TargetLowering *TLI = Subtarget->getTargetLowering();
14976 if (TLI->isConstTrueVal(N1) &&
14977 (N0->getOpcode() == ARMISD::VCMP || N0->getOpcode() == ARMISD::VCMPZ)) {
14978 if (CanInvertMVEVCMP(N0)) {
14979 SDLoc DL(N0);
14981
14983 Ops.push_back(N0->getOperand(0));
14984 if (N0->getOpcode() == ARMISD::VCMP)
14985 Ops.push_back(N0->getOperand(1));
14986 Ops.push_back(DAG.getConstant(CC, DL, MVT::i32));
14987 return DAG.getNode(N0->getOpcode(), DL, N0->getValueType(0), Ops);
14988 }
14989 }
14990 }
14991
14992 return SDValue();
14993}
14994
14995// ParseBFI - given a BFI instruction in N, extract the "from" value (Rn) and return it,
14996// and fill in FromMask and ToMask with (consecutive) bits in "from" to be extracted and
14997// their position in "to" (Rd).
14998static SDValue ParseBFI(SDNode *N, APInt &ToMask, APInt &FromMask) {
14999 assert(N->getOpcode() == ARMISD::BFI);
15000
15001 SDValue From = N->getOperand(1);
15002 ToMask = ~N->getConstantOperandAPInt(2);
15003 FromMask = APInt::getLowBitsSet(ToMask.getBitWidth(), ToMask.popcount());
15004
15005 // If the Base came from a SHR #C, we can deduce that it is really testing bit
15006 // #C in the base of the SHR.
15007 if (From->getOpcode() == ISD::SRL &&
15008 isa<ConstantSDNode>(From->getOperand(1))) {
15009 APInt Shift = From->getConstantOperandAPInt(1);
15010 assert(Shift.getLimitedValue() < 32 && "Shift too large!");
15011 FromMask <<= Shift.getLimitedValue(31);
15012 From = From->getOperand(0);
15013 }
15014
15015 return From;
15016}
15017
15018// If A and B contain one contiguous set of bits, does A | B == A . B?
15019//
15020// Neither A nor B must be zero.
15021static bool BitsProperlyConcatenate(const APInt &A, const APInt &B) {
15022 unsigned LastActiveBitInA = A.countr_zero();
15023 unsigned FirstActiveBitInB = B.getBitWidth() - B.countl_zero() - 1;
15024 return LastActiveBitInA - 1 == FirstActiveBitInB;
15025}
15026
15028 // We have a BFI in N. Find a BFI it can combine with, if one exists.
15029 APInt ToMask, FromMask;
15030 SDValue From = ParseBFI(N, ToMask, FromMask);
15031 SDValue To = N->getOperand(0);
15032
15033 SDValue V = To;
15034 if (V.getOpcode() != ARMISD::BFI)
15035 return SDValue();
15036
15037 APInt NewToMask, NewFromMask;
15038 SDValue NewFrom = ParseBFI(V.getNode(), NewToMask, NewFromMask);
15039 if (NewFrom != From)
15040 return SDValue();
15041
15042 // Do the written bits conflict with any we've seen so far?
15043 if ((NewToMask & ToMask).getBoolValue())
15044 // Conflicting bits.
15045 return SDValue();
15046
15047 // Are the new bits contiguous when combined with the old bits?
15048 if (BitsProperlyConcatenate(ToMask, NewToMask) &&
15049 BitsProperlyConcatenate(FromMask, NewFromMask))
15050 return V;
15051 if (BitsProperlyConcatenate(NewToMask, ToMask) &&
15052 BitsProperlyConcatenate(NewFromMask, FromMask))
15053 return V;
15054
15055 return SDValue();
15056}
15057
15059 SDValue N0 = N->getOperand(0);
15060 SDValue N1 = N->getOperand(1);
15061
15062 if (N1.getOpcode() == ISD::AND) {
15063 // (bfi A, (and B, Mask1), Mask2) -> (bfi A, B, Mask2) iff
15064 // the bits being cleared by the AND are not demanded by the BFI.
15066 if (!N11C)
15067 return SDValue();
15068 unsigned InvMask = N->getConstantOperandVal(2);
15069 unsigned LSB = llvm::countr_zero(~InvMask);
15070 unsigned Width = llvm::bit_width<unsigned>(~InvMask) - LSB;
15071 assert(Width <
15072 static_cast<unsigned>(std::numeric_limits<unsigned>::digits) &&
15073 "undefined behavior");
15074 unsigned Mask = (1u << Width) - 1;
15075 unsigned Mask2 = N11C->getZExtValue();
15076 if ((Mask & (~Mask2)) == 0)
15077 return DAG.getNode(ARMISD::BFI, SDLoc(N), N->getValueType(0),
15078 N->getOperand(0), N1.getOperand(0), N->getOperand(2));
15079 return SDValue();
15080 }
15081
15082 // Look for another BFI to combine with.
15083 if (SDValue CombineBFI = FindBFIToCombineWith(N)) {
15084 // We've found a BFI.
15085 APInt ToMask1, FromMask1;
15086 SDValue From1 = ParseBFI(N, ToMask1, FromMask1);
15087
15088 APInt ToMask2, FromMask2;
15089 SDValue From2 = ParseBFI(CombineBFI.getNode(), ToMask2, FromMask2);
15090 assert(From1 == From2);
15091 (void)From2;
15092
15093 // Create a new BFI, combining the two together.
15094 APInt NewFromMask = FromMask1 | FromMask2;
15095 APInt NewToMask = ToMask1 | ToMask2;
15096
15097 EVT VT = N->getValueType(0);
15098 SDLoc dl(N);
15099
15100 if (NewFromMask[0] == 0)
15101 From1 = DAG.getNode(ISD::SRL, dl, VT, From1,
15102 DAG.getConstant(NewFromMask.countr_zero(), dl, VT));
15103 return DAG.getNode(ARMISD::BFI, dl, VT, CombineBFI.getOperand(0), From1,
15104 DAG.getConstant(~NewToMask, dl, VT));
15105 }
15106
15107 // Reassociate BFI(BFI (A, B, M1), C, M2) to BFI(BFI (A, C, M2), B, M1) so
15108 // that lower bit insertions are performed first, providing that M1 and M2
15109 // do no overlap. This can allow multiple BFI instructions to be combined
15110 // together by the other folds above.
15111 if (N->getOperand(0).getOpcode() == ARMISD::BFI) {
15112 APInt ToMask1 = ~N->getConstantOperandAPInt(2);
15113 APInt ToMask2 = ~N0.getConstantOperandAPInt(2);
15114
15115 if (!N0.hasOneUse() || (ToMask1 & ToMask2) != 0 ||
15116 ToMask1.countl_zero() < ToMask2.countl_zero())
15117 return SDValue();
15118
15119 EVT VT = N->getValueType(0);
15120 SDLoc dl(N);
15121 SDValue BFI1 = DAG.getNode(ARMISD::BFI, dl, VT, N0.getOperand(0),
15122 N->getOperand(1), N->getOperand(2));
15123 return DAG.getNode(ARMISD::BFI, dl, VT, BFI1, N0.getOperand(1),
15124 N0.getOperand(2));
15125 }
15126
15127 return SDValue();
15128}
15129
15130// Check that N is CMPZ(CSINC(0, 0, CC, X)),
15131// or CMPZ(CMOV(1, 0, CC, X))
15132// return X if valid.
15134 if (Cmp->getOpcode() != ARMISD::CMPZ || !isNullConstant(Cmp->getOperand(1)))
15135 return SDValue();
15136 SDValue CSInc = Cmp->getOperand(0);
15137
15138 // Ignore any `And 1` nodes that may not yet have been removed. We are
15139 // looking for a value that produces 1/0, so these have no effect on the
15140 // code.
15141 while (CSInc.getOpcode() == ISD::AND &&
15142 isa<ConstantSDNode>(CSInc.getOperand(1)) &&
15143 CSInc.getConstantOperandVal(1) == 1 && CSInc->hasOneUse())
15144 CSInc = CSInc.getOperand(0);
15145
15146 if (CSInc.getOpcode() == ARMISD::CSINC &&
15147 isNullConstant(CSInc.getOperand(0)) &&
15148 isNullConstant(CSInc.getOperand(1)) && CSInc->hasOneUse()) {
15150 return CSInc.getOperand(3);
15151 }
15152 if (CSInc.getOpcode() == ARMISD::CMOV && isOneConstant(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(1)) &&
15158 isNullConstant(CSInc.getOperand(0)) && CSInc->hasOneUse()) {
15161 return CSInc.getOperand(3);
15162 }
15163 return SDValue();
15164}
15165
15167 // Given CMPZ(CSINC(C, 0, 0, EQ), 0), we can just use C directly. As in
15168 // t92: flags = ARMISD::CMPZ t74, 0
15169 // t93: i32 = ARMISD::CSINC 0, 0, 1, t92
15170 // t96: flags = ARMISD::CMPZ t93, 0
15171 // t114: i32 = ARMISD::CSINV 0, 0, 0, t96
15173 if (SDValue C = IsCMPZCSINC(N, Cond))
15174 if (Cond == ARMCC::EQ)
15175 return C;
15176 return SDValue();
15177}
15178
15180 // Fold away an unnecessary CMPZ/CSINC
15181 // CSXYZ A, B, C1 (CMPZ (CSINC 0, 0, C2, D), 0) ->
15182 // if C1==EQ -> CSXYZ A, B, C2, D
15183 // if C1==NE -> CSXYZ A, B, NOT(C2), D
15185 if (SDValue C = IsCMPZCSINC(N->getOperand(3).getNode(), Cond)) {
15186 if (N->getConstantOperandVal(2) == ARMCC::EQ)
15187 return DAG.getNode(N->getOpcode(), SDLoc(N), MVT::i32, N->getOperand(0),
15188 N->getOperand(1),
15189 DAG.getConstant(Cond, SDLoc(N), MVT::i32), C);
15190 if (N->getConstantOperandVal(2) == ARMCC::NE)
15191 return DAG.getNode(
15192 N->getOpcode(), SDLoc(N), MVT::i32, N->getOperand(0),
15193 N->getOperand(1),
15195 }
15196 return SDValue();
15197}
15198
15199/// PerformVMOVRRDCombine - Target-specific dag combine xforms for
15200/// ARMISD::VMOVRRD.
15203 const ARMSubtarget *Subtarget) {
15204 // vmovrrd(vmovdrr x, y) -> x,y
15205 SDValue InDouble = N->getOperand(0);
15206 if (InDouble.getOpcode() == ARMISD::VMOVDRR && Subtarget->hasFP64())
15207 return DCI.CombineTo(N, InDouble.getOperand(0), InDouble.getOperand(1));
15208
15209 // vmovrrd(load f64) -> (load i32), (load i32)
15210 SDNode *InNode = InDouble.getNode();
15211 if (ISD::isNormalLoad(InNode) && InNode->hasOneUse() &&
15212 InNode->getValueType(0) == MVT::f64 &&
15213 InNode->getOperand(1).getOpcode() == ISD::FrameIndex &&
15214 !cast<LoadSDNode>(InNode)->isVolatile()) {
15215 // TODO: Should this be done for non-FrameIndex operands?
15216 LoadSDNode *LD = cast<LoadSDNode>(InNode);
15217
15218 SelectionDAG &DAG = DCI.DAG;
15219 SDLoc DL(LD);
15220 SDValue BasePtr = LD->getBasePtr();
15221 SDValue NewLD1 =
15222 DAG.getLoad(MVT::i32, DL, LD->getChain(), BasePtr, LD->getPointerInfo(),
15223 LD->getAlign(), LD->getMemOperand()->getFlags());
15224
15225 SDValue OffsetPtr = DAG.getNode(ISD::ADD, DL, MVT::i32, BasePtr,
15226 DAG.getConstant(4, DL, MVT::i32));
15227
15228 SDValue NewLD2 = DAG.getLoad(MVT::i32, DL, LD->getChain(), OffsetPtr,
15229 LD->getPointerInfo().getWithOffset(4),
15230 commonAlignment(LD->getAlign(), 4),
15231 LD->getMemOperand()->getFlags());
15232
15233 DAG.ReplaceAllUsesOfValueWith(SDValue(LD, 1), NewLD2.getValue(1));
15234 if (DCI.DAG.getDataLayout().isBigEndian())
15235 std::swap (NewLD1, NewLD2);
15236 SDValue Result = DCI.CombineTo(N, NewLD1, NewLD2);
15237 return Result;
15238 }
15239
15240 // VMOVRRD(extract(..(build_vector(a, b, c, d)))) -> a,b or c,d
15241 // VMOVRRD(extract(insert_vector(insert_vector(.., a, l1), b, l2))) -> a,b
15242 if (InDouble.getOpcode() == ISD::EXTRACT_VECTOR_ELT &&
15243 isa<ConstantSDNode>(InDouble.getOperand(1))) {
15244 SDValue BV = InDouble.getOperand(0);
15245 // Look up through any nop bitcasts and vector_reg_casts. bitcasts may
15246 // change lane order under big endian.
15247 bool BVSwap = BV.getOpcode() == ISD::BITCAST;
15248 while (
15249 (BV.getOpcode() == ISD::BITCAST ||
15250 BV.getOpcode() == ARMISD::VECTOR_REG_CAST) &&
15251 (BV.getValueType() == MVT::v2f64 || BV.getValueType() == MVT::v2i64)) {
15252 BVSwap = BV.getOpcode() == ISD::BITCAST;
15253 BV = BV.getOperand(0);
15254 }
15255 if (BV.getValueType() != MVT::v4i32)
15256 return SDValue();
15257
15258 // Handle buildvectors, pulling out the correct lane depending on
15259 // endianness.
15260 unsigned Offset = InDouble.getConstantOperandVal(1) == 1 ? 2 : 0;
15261 if (BV.getOpcode() == ISD::BUILD_VECTOR) {
15262 SDValue Op0 = BV.getOperand(Offset);
15263 SDValue Op1 = BV.getOperand(Offset + 1);
15264 if (!Subtarget->isLittle() && BVSwap)
15265 std::swap(Op0, Op1);
15266
15267 return DCI.DAG.getMergeValues({Op0, Op1}, SDLoc(N));
15268 }
15269
15270 // A chain of insert_vectors, grabbing the correct value of the chain of
15271 // inserts.
15272 SDValue Op0, Op1;
15273 while (BV.getOpcode() == ISD::INSERT_VECTOR_ELT) {
15274 if (isa<ConstantSDNode>(BV.getOperand(2))) {
15275 if (BV.getConstantOperandVal(2) == Offset && !Op0)
15276 Op0 = BV.getOperand(1);
15277 if (BV.getConstantOperandVal(2) == Offset + 1 && !Op1)
15278 Op1 = BV.getOperand(1);
15279 }
15280 BV = BV.getOperand(0);
15281 }
15282 if (!Subtarget->isLittle() && BVSwap)
15283 std::swap(Op0, Op1);
15284 if (Op0 && Op1)
15285 return DCI.DAG.getMergeValues({Op0, Op1}, SDLoc(N));
15286 }
15287
15288 return SDValue();
15289}
15290
15291/// PerformVMOVDRRCombine - Target-specific dag combine xforms for
15292/// ARMISD::VMOVDRR. This is also used for BUILD_VECTORs with 2 operands.
15294 // N=vmovrrd(X); vmovdrr(N:0, N:1) -> bit_convert(X)
15295 SDValue Op0 = N->getOperand(0);
15296 SDValue Op1 = N->getOperand(1);
15297 if (Op0.getOpcode() == ISD::BITCAST)
15298 Op0 = Op0.getOperand(0);
15299 if (Op1.getOpcode() == ISD::BITCAST)
15300 Op1 = Op1.getOperand(0);
15301 if (Op0.getOpcode() == ARMISD::VMOVRRD &&
15302 Op0.getNode() == Op1.getNode() &&
15303 Op0.getResNo() == 0 && Op1.getResNo() == 1)
15304 return DAG.getNode(ISD::BITCAST, SDLoc(N),
15305 N->getValueType(0), Op0.getOperand(0));
15306 return SDValue();
15307}
15308
15311 SDValue Op0 = N->getOperand(0);
15312
15313 // VMOVhr (VMOVrh (X)) -> X
15314 if (Op0->getOpcode() == ARMISD::VMOVrh)
15315 return Op0->getOperand(0);
15316
15317 // FullFP16: half values are passed in S-registers, and we don't
15318 // need any of the bitcast and moves:
15319 //
15320 // t2: f32,ch1,gl1? = CopyFromReg ch, Register:f32 %0, gl?
15321 // t5: i32 = bitcast t2
15322 // t18: f16 = ARMISD::VMOVhr t5
15323 // =>
15324 // tN: f16,ch2,gl2? = CopyFromReg ch, Register::f32 %0, gl?
15325 if (Op0->getOpcode() == ISD::BITCAST) {
15326 SDValue Copy = Op0->getOperand(0);
15327 if (Copy.getValueType() == MVT::f32 &&
15328 Copy->getOpcode() == ISD::CopyFromReg) {
15329 bool HasGlue = Copy->getNumOperands() == 3;
15330 SDValue Ops[] = {Copy->getOperand(0), Copy->getOperand(1),
15331 HasGlue ? Copy->getOperand(2) : SDValue()};
15332 EVT OutTys[] = {N->getValueType(0), MVT::Other, MVT::Glue};
15333 SDValue NewCopy =
15335 DCI.DAG.getVTList(ArrayRef(OutTys, HasGlue ? 3 : 2)),
15336 ArrayRef(Ops, HasGlue ? 3 : 2));
15337
15338 // Update Users, Chains, and Potential Glue.
15339 DCI.DAG.ReplaceAllUsesOfValueWith(SDValue(N, 0), NewCopy.getValue(0));
15340 DCI.DAG.ReplaceAllUsesOfValueWith(Copy.getValue(1), NewCopy.getValue(1));
15341 if (HasGlue)
15342 DCI.DAG.ReplaceAllUsesOfValueWith(Copy.getValue(2),
15343 NewCopy.getValue(2));
15344
15345 return NewCopy;
15346 }
15347 }
15348
15349 // fold (VMOVhr (load x)) -> (load (f16*)x)
15350 if (LoadSDNode *LN0 = dyn_cast<LoadSDNode>(Op0)) {
15351 if (LN0->hasOneUse() && LN0->isUnindexed() &&
15352 LN0->getMemoryVT() == MVT::i16) {
15353 SDValue Load =
15354 DCI.DAG.getLoad(N->getValueType(0), SDLoc(N), LN0->getChain(),
15355 LN0->getBasePtr(), LN0->getMemOperand());
15356 DCI.DAG.ReplaceAllUsesOfValueWith(SDValue(N, 0), Load.getValue(0));
15357 DCI.DAG.ReplaceAllUsesOfValueWith(Op0.getValue(1), Load.getValue(1));
15358 return Load;
15359 }
15360 }
15361
15362 // Only the bottom 16 bits of the source register are used.
15363 APInt DemandedMask = APInt::getLowBitsSet(32, 16);
15364 const TargetLowering &TLI = DCI.DAG.getTargetLoweringInfo();
15365 if (TLI.SimplifyDemandedBits(Op0, DemandedMask, DCI))
15366 return SDValue(N, 0);
15367
15368 return SDValue();
15369}
15370
15372 SDValue N0 = N->getOperand(0);
15373 EVT VT = N->getValueType(0);
15374
15375 // fold (VMOVrh (fpconst x)) -> const x
15377 APFloat V = C->getValueAPF();
15378 return DAG.getConstant(V.bitcastToAPInt().getZExtValue(), SDLoc(N), VT);
15379 }
15380
15381 // fold (VMOVrh (load x)) -> (zextload (i16*)x)
15382 if (ISD::isNormalLoad(N0.getNode()) && N0.hasOneUse()) {
15383 LoadSDNode *LN0 = cast<LoadSDNode>(N0);
15384
15385 SDValue Load =
15386 DAG.getExtLoad(ISD::ZEXTLOAD, SDLoc(N), VT, LN0->getChain(),
15387 LN0->getBasePtr(), MVT::i16, LN0->getMemOperand());
15388 DAG.ReplaceAllUsesOfValueWith(SDValue(N, 0), Load.getValue(0));
15389 DAG.ReplaceAllUsesOfValueWith(N0.getValue(1), Load.getValue(1));
15390 return Load;
15391 }
15392
15393 // Fold VMOVrh(extract(x, n)) -> vgetlaneu(x, n)
15394 if (N0->getOpcode() == ISD::EXTRACT_VECTOR_ELT &&
15396 return DAG.getNode(ARMISD::VGETLANEu, SDLoc(N), VT, N0->getOperand(0),
15397 N0->getOperand(1));
15398
15399 return SDValue();
15400}
15401
15402/// hasNormalLoadOperand - Check if any of the operands of a BUILD_VECTOR node
15403/// are normal, non-volatile loads. If so, it is profitable to bitcast an
15404/// i64 vector to have f64 elements, since the value can then be loaded
15405/// directly into a VFP register.
15407 unsigned NumElts = N->getValueType(0).getVectorNumElements();
15408 for (unsigned i = 0; i < NumElts; ++i) {
15409 SDNode *Elt = N->getOperand(i).getNode();
15410 if (ISD::isNormalLoad(Elt) && !cast<LoadSDNode>(Elt)->isVolatile())
15411 return true;
15412 }
15413 return false;
15414}
15415
15416/// PerformBUILD_VECTORCombine - Target-specific dag combine xforms for
15417/// ISD::BUILD_VECTOR.
15420 const ARMSubtarget *Subtarget) {
15421 // build_vector(N=ARMISD::VMOVRRD(X), N:1) -> bit_convert(X):
15422 // VMOVRRD is introduced when legalizing i64 types. It forces the i64 value
15423 // into a pair of GPRs, which is fine when the value is used as a scalar,
15424 // but if the i64 value is converted to a vector, we need to undo the VMOVRRD.
15425 SelectionDAG &DAG = DCI.DAG;
15426 if (N->getNumOperands() == 2)
15427 if (SDValue RV = PerformVMOVDRRCombine(N, DAG))
15428 return RV;
15429
15430 // Load i64 elements as f64 values so that type legalization does not split
15431 // them up into i32 values.
15432 EVT VT = N->getValueType(0);
15433 if (VT.getVectorElementType() != MVT::i64 || !hasNormalLoadOperand(N))
15434 return SDValue();
15435 SDLoc dl(N);
15437 unsigned NumElts = VT.getVectorNumElements();
15438 for (unsigned i = 0; i < NumElts; ++i) {
15439 SDValue V = DAG.getNode(ISD::BITCAST, dl, MVT::f64, N->getOperand(i));
15440 Ops.push_back(V);
15441 // Make the DAGCombiner fold the bitcast.
15442 DCI.AddToWorklist(V.getNode());
15443 }
15444 EVT FloatVT = EVT::getVectorVT(*DAG.getContext(), MVT::f64, NumElts);
15445 SDValue BV = DAG.getBuildVector(FloatVT, dl, Ops);
15446 return DAG.getNode(ISD::BITCAST, dl, VT, BV);
15447}
15448
15449/// Target-specific dag combine xforms for ARMISD::BUILD_VECTOR.
15450static SDValue
15452 // ARMISD::BUILD_VECTOR is introduced when legalizing ISD::BUILD_VECTOR.
15453 // At that time, we may have inserted bitcasts from integer to float.
15454 // If these bitcasts have survived DAGCombine, change the lowering of this
15455 // BUILD_VECTOR in something more vector friendly, i.e., that does not
15456 // force to use floating point types.
15457
15458 // Make sure we can change the type of the vector.
15459 // This is possible iff:
15460 // 1. The vector is only used in a bitcast to a integer type. I.e.,
15461 // 1.1. Vector is used only once.
15462 // 1.2. Use is a bit convert to an integer type.
15463 // 2. The size of its operands are 32-bits (64-bits are not legal).
15464 EVT VT = N->getValueType(0);
15465 EVT EltVT = VT.getVectorElementType();
15466
15467 // Check 1.1. and 2.
15468 if (EltVT.getSizeInBits() != 32 || !N->hasOneUse())
15469 return SDValue();
15470
15471 // By construction, the input type must be float.
15472 assert(EltVT == MVT::f32 && "Unexpected type!");
15473
15474 // Check 1.2.
15475 SDNode *Use = *N->user_begin();
15476 if (Use->getOpcode() != ISD::BITCAST ||
15477 Use->getValueType(0).isFloatingPoint())
15478 return SDValue();
15479
15480 // Check profitability.
15481 // Model is, if more than half of the relevant operands are bitcast from
15482 // i32, turn the build_vector into a sequence of insert_vector_elt.
15483 // Relevant operands are everything that is not statically
15484 // (i.e., at compile time) bitcasted.
15485 unsigned NumOfBitCastedElts = 0;
15486 unsigned NumElts = VT.getVectorNumElements();
15487 unsigned NumOfRelevantElts = NumElts;
15488 for (unsigned Idx = 0; Idx < NumElts; ++Idx) {
15489 SDValue Elt = N->getOperand(Idx);
15490 if (Elt->getOpcode() == ISD::BITCAST) {
15491 // Assume only bit cast to i32 will go away.
15492 if (Elt->getOperand(0).getValueType() == MVT::i32)
15493 ++NumOfBitCastedElts;
15494 } else if (Elt.isUndef() || isa<ConstantSDNode>(Elt))
15495 // Constants are statically casted, thus do not count them as
15496 // relevant operands.
15497 --NumOfRelevantElts;
15498 }
15499
15500 // Check if more than half of the elements require a non-free bitcast.
15501 if (NumOfBitCastedElts <= NumOfRelevantElts / 2)
15502 return SDValue();
15503
15504 SelectionDAG &DAG = DCI.DAG;
15505 // Create the new vector type.
15506 EVT VecVT = EVT::getVectorVT(*DAG.getContext(), MVT::i32, NumElts);
15507 // Check if the type is legal.
15508 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
15509 if (!TLI.isTypeLegal(VecVT))
15510 return SDValue();
15511
15512 // Combine:
15513 // ARMISD::BUILD_VECTOR E1, E2, ..., EN.
15514 // => BITCAST INSERT_VECTOR_ELT
15515 // (INSERT_VECTOR_ELT (...), (BITCAST EN-1), N-1),
15516 // (BITCAST EN), N.
15517 SDValue Vec = DAG.getUNDEF(VecVT);
15518 SDLoc dl(N);
15519 for (unsigned Idx = 0 ; Idx < NumElts; ++Idx) {
15520 SDValue V = N->getOperand(Idx);
15521 if (V.isUndef())
15522 continue;
15523 if (V.getOpcode() == ISD::BITCAST &&
15524 V->getOperand(0).getValueType() == MVT::i32)
15525 // Fold obvious case.
15526 V = V.getOperand(0);
15527 else {
15528 V = DAG.getNode(ISD::BITCAST, SDLoc(V), MVT::i32, V);
15529 // Make the DAGCombiner fold the bitcasts.
15530 DCI.AddToWorklist(V.getNode());
15531 }
15532 SDValue LaneIdx = DAG.getConstant(Idx, dl, MVT::i32);
15533 Vec = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, VecVT, Vec, V, LaneIdx);
15534 }
15535 Vec = DAG.getNode(ISD::BITCAST, dl, VT, Vec);
15536 // Make the DAGCombiner fold the bitcasts.
15537 DCI.AddToWorklist(Vec.getNode());
15538 return Vec;
15539}
15540
15541static SDValue
15543 EVT VT = N->getValueType(0);
15544 SDValue Op = N->getOperand(0);
15545 SDLoc dl(N);
15546
15547 // PREDICATE_CAST(PREDICATE_CAST(x)) == PREDICATE_CAST(x)
15548 if (Op->getOpcode() == ARMISD::PREDICATE_CAST) {
15549 // If the valuetypes are the same, we can remove the cast entirely.
15550 if (Op->getOperand(0).getValueType() == VT)
15551 return Op->getOperand(0);
15552 return DCI.DAG.getNode(ARMISD::PREDICATE_CAST, dl, VT, Op->getOperand(0));
15553 }
15554
15555 // Turn pred_cast(xor x, -1) into xor(pred_cast x, -1), in order to produce
15556 // more VPNOT which might get folded as else predicates.
15557 if (Op.getValueType() == MVT::i32 && isBitwiseNot(Op)) {
15558 SDValue X =
15559 DCI.DAG.getNode(ARMISD::PREDICATE_CAST, dl, VT, Op->getOperand(0));
15560 SDValue C = DCI.DAG.getNode(ARMISD::PREDICATE_CAST, dl, VT,
15561 DCI.DAG.getConstant(65535, dl, MVT::i32));
15562 return DCI.DAG.getNode(ISD::XOR, dl, VT, X, C);
15563 }
15564
15565 // Only the bottom 16 bits of the source register are used.
15566 if (Op.getValueType() == MVT::i32) {
15567 APInt DemandedMask = APInt::getLowBitsSet(32, 16);
15568 const TargetLowering &TLI = DCI.DAG.getTargetLoweringInfo();
15569 if (TLI.SimplifyDemandedBits(Op, DemandedMask, DCI))
15570 return SDValue(N, 0);
15571 }
15572 return SDValue();
15573}
15574
15576 const ARMSubtarget *ST) {
15577 EVT VT = N->getValueType(0);
15578 SDValue Op = N->getOperand(0);
15579 SDLoc dl(N);
15580
15581 // Under Little endian, a VECTOR_REG_CAST is equivalent to a BITCAST
15582 if (ST->isLittle())
15583 return DAG.getNode(ISD::BITCAST, dl, VT, Op);
15584
15585 // VT VECTOR_REG_CAST (VT Op) -> Op
15586 if (Op.getValueType() == VT)
15587 return Op;
15588 // VECTOR_REG_CAST undef -> undef
15589 if (Op.isUndef())
15590 return DAG.getUNDEF(VT);
15591
15592 // VECTOR_REG_CAST(VECTOR_REG_CAST(x)) == VECTOR_REG_CAST(x)
15593 if (Op->getOpcode() == ARMISD::VECTOR_REG_CAST) {
15594 // If the valuetypes are the same, we can remove the cast entirely.
15595 if (Op->getOperand(0).getValueType() == VT)
15596 return Op->getOperand(0);
15597 return DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, VT, Op->getOperand(0));
15598 }
15599
15600 return SDValue();
15601}
15602
15604 const ARMSubtarget *Subtarget) {
15605 if (!Subtarget->hasMVEIntegerOps())
15606 return SDValue();
15607
15608 EVT VT = N->getValueType(0);
15609 SDValue Op0 = N->getOperand(0);
15610 SDValue Op1 = N->getOperand(1);
15611 ARMCC::CondCodes Cond = (ARMCC::CondCodes)N->getConstantOperandVal(2);
15612 SDLoc dl(N);
15613
15614 // vcmp X, 0, cc -> vcmpz X, cc
15615 if (isZeroVector(Op1))
15616 return DAG.getNode(ARMISD::VCMPZ, dl, VT, Op0, N->getOperand(2));
15617
15618 unsigned SwappedCond = getSwappedCondition(Cond);
15619 if (isValidMVECond(SwappedCond, VT.isFloatingPoint())) {
15620 // vcmp 0, X, cc -> vcmpz X, reversed(cc)
15621 if (isZeroVector(Op0))
15622 return DAG.getNode(ARMISD::VCMPZ, dl, VT, Op1,
15623 DAG.getConstant(SwappedCond, dl, MVT::i32));
15624 // vcmp vdup(Y), X, cc -> vcmp X, vdup(Y), reversed(cc)
15625 if (Op0->getOpcode() == ARMISD::VDUP && Op1->getOpcode() != ARMISD::VDUP)
15626 return DAG.getNode(ARMISD::VCMP, dl, VT, Op1, Op0,
15627 DAG.getConstant(SwappedCond, dl, MVT::i32));
15628 }
15629
15630 return SDValue();
15631}
15632
15633/// PerformInsertEltCombine - Target-specific dag combine xforms for
15634/// ISD::INSERT_VECTOR_ELT.
15637 // Bitcast an i64 load inserted into a vector to f64.
15638 // Otherwise, the i64 value will be legalized to a pair of i32 values.
15639 EVT VT = N->getValueType(0);
15640 SDNode *Elt = N->getOperand(1).getNode();
15641 if (VT.getVectorElementType() != MVT::i64 ||
15642 !ISD::isNormalLoad(Elt) || cast<LoadSDNode>(Elt)->isVolatile())
15643 return SDValue();
15644
15645 SelectionDAG &DAG = DCI.DAG;
15646 SDLoc dl(N);
15647 EVT FloatVT = EVT::getVectorVT(*DAG.getContext(), MVT::f64,
15649 SDValue Vec = DAG.getNode(ISD::BITCAST, dl, FloatVT, N->getOperand(0));
15650 SDValue V = DAG.getNode(ISD::BITCAST, dl, MVT::f64, N->getOperand(1));
15651 // Make the DAGCombiner fold the bitcasts.
15652 DCI.AddToWorklist(Vec.getNode());
15653 DCI.AddToWorklist(V.getNode());
15654 SDValue InsElt = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, FloatVT,
15655 Vec, V, N->getOperand(2));
15656 return DAG.getNode(ISD::BITCAST, dl, VT, InsElt);
15657}
15658
15659// Convert a pair of extracts from the same base vector to a VMOVRRD. Either
15660// directly or bitcast to an integer if the original is a float vector.
15661// extract(x, n); extract(x, n+1) -> VMOVRRD(extract v2f64 x, n/2)
15662// bitcast(extract(x, n)); bitcast(extract(x, n+1)) -> VMOVRRD(extract x, n/2)
15663static SDValue
15665 EVT VT = N->getValueType(0);
15666 SDLoc dl(N);
15667
15668 if (!DCI.isAfterLegalizeDAG() || VT != MVT::i32 ||
15669 !DCI.DAG.getTargetLoweringInfo().isTypeLegal(MVT::f64))
15670 return SDValue();
15671
15672 SDValue Ext = SDValue(N, 0);
15673 if (Ext.getOpcode() == ISD::BITCAST &&
15674 Ext.getOperand(0).getValueType() == MVT::f32)
15675 Ext = Ext.getOperand(0);
15676 if (Ext.getOpcode() != ISD::EXTRACT_VECTOR_ELT ||
15678 Ext.getConstantOperandVal(1) % 2 != 0)
15679 return SDValue();
15680 if (Ext->hasOneUse() && (Ext->user_begin()->getOpcode() == ISD::SINT_TO_FP ||
15681 Ext->user_begin()->getOpcode() == ISD::UINT_TO_FP))
15682 return SDValue();
15683
15684 SDValue Op0 = Ext.getOperand(0);
15685 EVT VecVT = Op0.getValueType();
15686 unsigned ResNo = Op0.getResNo();
15687 unsigned Lane = Ext.getConstantOperandVal(1);
15688 if (VecVT.getVectorNumElements() != 4)
15689 return SDValue();
15690
15691 // Find another extract, of Lane + 1
15692 auto OtherIt = find_if(Op0->users(), [&](SDNode *V) {
15693 return V->getOpcode() == ISD::EXTRACT_VECTOR_ELT &&
15694 isa<ConstantSDNode>(V->getOperand(1)) &&
15695 V->getConstantOperandVal(1) == Lane + 1 &&
15696 V->getOperand(0).getResNo() == ResNo;
15697 });
15698 if (OtherIt == Op0->users().end())
15699 return SDValue();
15700
15701 // For float extracts, we need to be converting to a i32 for both vector
15702 // lanes.
15703 SDValue OtherExt(*OtherIt, 0);
15704 if (OtherExt.getValueType() != MVT::i32) {
15705 if (!OtherExt->hasOneUse() ||
15706 OtherExt->user_begin()->getOpcode() != ISD::BITCAST ||
15707 OtherExt->user_begin()->getValueType(0) != MVT::i32)
15708 return SDValue();
15709 OtherExt = SDValue(*OtherExt->user_begin(), 0);
15710 }
15711
15712 // Convert the type to a f64 and extract with a VMOVRRD.
15713 SDValue F64 = DCI.DAG.getNode(
15714 ISD::EXTRACT_VECTOR_ELT, dl, MVT::f64,
15715 DCI.DAG.getNode(ARMISD::VECTOR_REG_CAST, dl, MVT::v2f64, Op0),
15716 DCI.DAG.getConstant(Ext.getConstantOperandVal(1) / 2, dl, MVT::i32));
15717 SDValue VMOVRRD =
15718 DCI.DAG.getNode(ARMISD::VMOVRRD, dl, {MVT::i32, MVT::i32}, F64);
15719
15720 DCI.CombineTo(OtherExt.getNode(), SDValue(VMOVRRD.getNode(), 1));
15721 return VMOVRRD;
15722}
15723
15726 const ARMSubtarget *ST) {
15727 SDValue Op0 = N->getOperand(0);
15728 EVT VT = N->getValueType(0);
15729 SDLoc dl(N);
15730
15731 // extract (vdup x) -> x
15732 if (Op0->getOpcode() == ARMISD::VDUP) {
15733 SDValue X = Op0->getOperand(0);
15734 if (VT == MVT::f16 && X.getValueType() == MVT::i32)
15735 return DCI.DAG.getNode(ARMISD::VMOVhr, dl, VT, X);
15736 if (VT == MVT::i32 && X.getValueType() == MVT::f16)
15737 return DCI.DAG.getNode(ARMISD::VMOVrh, dl, VT, X);
15738 if (VT == MVT::f32 && X.getValueType() == MVT::i32)
15739 return DCI.DAG.getNode(ISD::BITCAST, dl, VT, X);
15740
15741 while (X.getValueType() != VT && X->getOpcode() == ISD::BITCAST)
15742 X = X->getOperand(0);
15743 if (X.getValueType() == VT)
15744 return X;
15745 }
15746
15747 // extract ARM_BUILD_VECTOR -> x
15748 if (Op0->getOpcode() == ARMISD::BUILD_VECTOR &&
15749 isa<ConstantSDNode>(N->getOperand(1)) &&
15750 N->getConstantOperandVal(1) < Op0.getNumOperands()) {
15751 return Op0.getOperand(N->getConstantOperandVal(1));
15752 }
15753
15754 // extract(bitcast(BUILD_VECTOR(VMOVDRR(a, b), ..))) -> a or b
15755 if (Op0.getValueType() == MVT::v4i32 &&
15756 isa<ConstantSDNode>(N->getOperand(1)) &&
15757 Op0.getOpcode() == ISD::BITCAST &&
15759 Op0.getOperand(0).getValueType() == MVT::v2f64) {
15760 SDValue BV = Op0.getOperand(0);
15761 unsigned Offset = N->getConstantOperandVal(1);
15762 SDValue MOV = BV.getOperand(Offset < 2 ? 0 : 1);
15763 if (MOV.getOpcode() == ARMISD::VMOVDRR)
15764 return MOV.getOperand(ST->isLittle() ? Offset % 2 : 1 - Offset % 2);
15765 }
15766
15767 // extract x, n; extract x, n+1 -> VMOVRRD x
15768 if (SDValue R = PerformExtractEltToVMOVRRD(N, DCI))
15769 return R;
15770
15771 // extract (MVETrunc(x)) -> extract x
15772 if (Op0->getOpcode() == ARMISD::MVETRUNC) {
15773 unsigned Idx = N->getConstantOperandVal(1);
15774 unsigned Vec =
15776 unsigned SubIdx =
15778 return DCI.DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, VT, Op0.getOperand(Vec),
15779 DCI.DAG.getConstant(SubIdx, dl, MVT::i32));
15780 }
15781
15782 // extract(bitcast(BUILD_VECTOR(extract(bitcast(a)), ..))) -> extract(a)
15783 if (ST->isLittle() && Op0.getOpcode() == ISD::BITCAST &&
15785 isa<ConstantSDNode>(N->getOperand(1)) &&
15788 unsigned Lane = N->getConstantOperandVal(1);
15789 EVT ExtVT = Op0.getValueType();
15790 EVT BVVT = Op0.getOperand(0).getValueType();
15791 unsigned BVLane =
15792 (Lane * BVVT.getVectorNumElements()) / ExtVT.getVectorNumElements();
15793 assert(BVLane < Op0.getOperand(0).getNumOperands());
15794 SDValue Ext = Op0.getOperand(0).getOperand(BVLane);
15795 if (Ext.getOpcode() == ISD::EXTRACT_VECTOR_ELT &&
15796 Ext.getOperand(0).getOpcode() == ISD::BITCAST &&
15798 Ext.getOperand(0).getOperand(0).getValueType() == ExtVT) {
15799 unsigned InnerLane = Ext.getConstantOperandVal(1);
15800 unsigned BVSubLane = Lane - (BVLane * ExtVT.getVectorNumElements()) /
15801 BVVT.getVectorNumElements();
15802 unsigned FinalLane = (InnerLane * ExtVT.getVectorNumElements()) /
15803 BVVT.getVectorNumElements() +
15804 BVSubLane;
15805 return DCI.DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, VT,
15806 Ext.getOperand(0).getOperand(0),
15807 DCI.DAG.getConstant(FinalLane, dl, MVT::i32));
15808 }
15809 }
15810
15811 return SDValue();
15812}
15813
15815 SDValue Op = N->getOperand(0);
15816 EVT VT = N->getValueType(0);
15817
15818 // sext_inreg(VGETLANEu) -> VGETLANEs
15819 if (Op.getOpcode() == ARMISD::VGETLANEu &&
15820 cast<VTSDNode>(N->getOperand(1))->getVT() ==
15821 Op.getOperand(0).getValueType().getScalarType())
15822 return DAG.getNode(ARMISD::VGETLANEs, SDLoc(N), VT, Op.getOperand(0),
15823 Op.getOperand(1));
15824
15825 return SDValue();
15826}
15827
15828static SDValue
15830 SDValue Vec = N->getOperand(0);
15831 SDValue SubVec = N->getOperand(1);
15832 uint64_t IdxVal = N->getConstantOperandVal(2);
15833 EVT VecVT = Vec.getValueType();
15834 EVT SubVT = SubVec.getValueType();
15835
15836 // Only do this for legal fixed vector types.
15837 if (!VecVT.isFixedLengthVector() ||
15838 !DCI.DAG.getTargetLoweringInfo().isTypeLegal(VecVT) ||
15840 return SDValue();
15841
15842 // Ignore widening patterns.
15843 if (IdxVal == 0 && Vec.isUndef())
15844 return SDValue();
15845
15846 // Subvector must be half the width and an "aligned" insertion.
15847 unsigned NumSubElts = SubVT.getVectorNumElements();
15848 if ((SubVT.getSizeInBits() * 2) != VecVT.getSizeInBits() ||
15849 (IdxVal != 0 && IdxVal != NumSubElts))
15850 return SDValue();
15851
15852 // Fold insert_subvector -> concat_vectors
15853 // insert_subvector(Vec,Sub,lo) -> concat_vectors(Sub,extract(Vec,hi))
15854 // insert_subvector(Vec,Sub,hi) -> concat_vectors(extract(Vec,lo),Sub)
15855 SDLoc DL(N);
15856 SDValue Lo, Hi;
15857 if (IdxVal == 0) {
15858 Lo = SubVec;
15859 Hi = DCI.DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, SubVT, Vec,
15860 DCI.DAG.getVectorIdxConstant(NumSubElts, DL));
15861 } else {
15862 Lo = DCI.DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, SubVT, Vec,
15863 DCI.DAG.getVectorIdxConstant(0, DL));
15864 Hi = SubVec;
15865 }
15866 return DCI.DAG.getNode(ISD::CONCAT_VECTORS, DL, VecVT, Lo, Hi);
15867}
15868
15869// shuffle(MVETrunc(x, y)) -> VMOVN(x, y)
15871 SelectionDAG &DAG) {
15872 SDValue Trunc = N->getOperand(0);
15873 EVT VT = Trunc.getValueType();
15874 if (Trunc.getOpcode() != ARMISD::MVETRUNC || !N->getOperand(1).isUndef())
15875 return SDValue();
15876
15877 SDLoc DL(Trunc);
15878 if (isVMOVNTruncMask(N->getMask(), VT, false))
15879 return DAG.getNode(
15880 ARMISD::VMOVN, DL, VT,
15881 DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, VT, Trunc.getOperand(0)),
15882 DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, VT, Trunc.getOperand(1)),
15883 DAG.getConstant(1, DL, MVT::i32));
15884 else if (isVMOVNTruncMask(N->getMask(), VT, true))
15885 return DAG.getNode(
15886 ARMISD::VMOVN, DL, VT,
15887 DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, VT, Trunc.getOperand(1)),
15888 DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, VT, Trunc.getOperand(0)),
15889 DAG.getConstant(1, DL, MVT::i32));
15890 return SDValue();
15891}
15892
15893/// PerformVECTOR_SHUFFLECombine - Target-specific dag combine xforms for
15894/// ISD::VECTOR_SHUFFLE.
15897 return R;
15898
15899 // The LLVM shufflevector instruction does not require the shuffle mask
15900 // length to match the operand vector length, but ISD::VECTOR_SHUFFLE does
15901 // have that requirement. When translating to ISD::VECTOR_SHUFFLE, if the
15902 // operands do not match the mask length, they are extended by concatenating
15903 // them with undef vectors. That is probably the right thing for other
15904 // targets, but for NEON it is better to concatenate two double-register
15905 // size vector operands into a single quad-register size vector. Do that
15906 // transformation here:
15907 // shuffle(concat(v1, undef), concat(v2, undef)) ->
15908 // shuffle(concat(v1, v2), undef)
15909 SDValue Op0 = N->getOperand(0);
15910 SDValue Op1 = N->getOperand(1);
15911 if (Op0.getOpcode() != ISD::CONCAT_VECTORS ||
15912 Op1.getOpcode() != ISD::CONCAT_VECTORS ||
15913 Op0.getNumOperands() != 2 ||
15914 Op1.getNumOperands() != 2)
15915 return SDValue();
15916 SDValue Concat0Op1 = Op0.getOperand(1);
15917 SDValue Concat1Op1 = Op1.getOperand(1);
15918 if (!Concat0Op1.isUndef() || !Concat1Op1.isUndef())
15919 return SDValue();
15920 // Skip the transformation if any of the types are illegal.
15921 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
15922 EVT VT = N->getValueType(0);
15923 if (!TLI.isTypeLegal(VT) ||
15924 !TLI.isTypeLegal(Concat0Op1.getValueType()) ||
15925 !TLI.isTypeLegal(Concat1Op1.getValueType()))
15926 return SDValue();
15927
15928 SDValue NewConcat = DAG.getNode(ISD::CONCAT_VECTORS, SDLoc(N), VT,
15929 Op0.getOperand(0), Op1.getOperand(0));
15930 // Translate the shuffle mask.
15931 SmallVector<int, 16> NewMask;
15932 unsigned NumElts = VT.getVectorNumElements();
15933 unsigned HalfElts = NumElts/2;
15935 for (unsigned n = 0; n < NumElts; ++n) {
15936 int MaskElt = SVN->getMaskElt(n);
15937 int NewElt = -1;
15938 if (MaskElt < (int)HalfElts)
15939 NewElt = MaskElt;
15940 else if (MaskElt >= (int)NumElts && MaskElt < (int)(NumElts + HalfElts))
15941 NewElt = HalfElts + MaskElt - NumElts;
15942 NewMask.push_back(NewElt);
15943 }
15944 return DAG.getVectorShuffle(VT, SDLoc(N), NewConcat,
15945 DAG.getUNDEF(VT), NewMask);
15946}
15947
15948/// Load/store instruction that can be merged with a base address
15949/// update
15954 unsigned AddrOpIdx;
15955};
15956
15958 /// Instruction that updates a pointer
15960 /// Pointer increment operand
15962 /// Pointer increment value if it is a constant, or 0 otherwise
15963 unsigned ConstInc;
15964};
15965
15967 // Check that the add is independent of the load/store.
15968 // Otherwise, folding it would create a cycle. Search through Addr
15969 // as well, since the User may not be a direct user of Addr and
15970 // only share a base pointer.
15973 Worklist.push_back(N);
15974 Worklist.push_back(User);
15975 const unsigned MaxSteps = 1024;
15976 if (SDNode::hasPredecessorHelper(N, Visited, Worklist, MaxSteps) ||
15977 SDNode::hasPredecessorHelper(User, Visited, Worklist, MaxSteps))
15978 return false;
15979 return true;
15980}
15981
15983 struct BaseUpdateUser &User,
15984 bool SimpleConstIncOnly,
15986 SelectionDAG &DAG = DCI.DAG;
15987 SDNode *N = Target.N;
15988 MemSDNode *MemN = cast<MemSDNode>(N);
15989 SDLoc dl(N);
15990
15991 // Find the new opcode for the updating load/store.
15992 bool isLoadOp = true;
15993 bool isLaneOp = false;
15994 // Workaround for vst1x and vld1x intrinsics which do not have alignment
15995 // as an operand.
15996 bool hasAlignment = true;
15997 unsigned NewOpc = 0;
15998 unsigned NumVecs = 0;
15999 if (Target.isIntrinsic) {
16000 unsigned IntNo = N->getConstantOperandVal(1);
16001 switch (IntNo) {
16002 default:
16003 llvm_unreachable("unexpected intrinsic for Neon base update");
16004 case Intrinsic::arm_neon_vld1:
16005 NewOpc = ARMISD::VLD1_UPD;
16006 NumVecs = 1;
16007 break;
16008 case Intrinsic::arm_neon_vld2:
16009 NewOpc = ARMISD::VLD2_UPD;
16010 NumVecs = 2;
16011 break;
16012 case Intrinsic::arm_neon_vld3:
16013 NewOpc = ARMISD::VLD3_UPD;
16014 NumVecs = 3;
16015 break;
16016 case Intrinsic::arm_neon_vld4:
16017 NewOpc = ARMISD::VLD4_UPD;
16018 NumVecs = 4;
16019 break;
16020 case Intrinsic::arm_neon_vld1x2:
16021 NewOpc = ARMISD::VLD1x2_UPD;
16022 NumVecs = 2;
16023 hasAlignment = false;
16024 break;
16025 case Intrinsic::arm_neon_vld1x3:
16026 NewOpc = ARMISD::VLD1x3_UPD;
16027 NumVecs = 3;
16028 hasAlignment = false;
16029 break;
16030 case Intrinsic::arm_neon_vld1x4:
16031 NewOpc = ARMISD::VLD1x4_UPD;
16032 NumVecs = 4;
16033 hasAlignment = false;
16034 break;
16035 case Intrinsic::arm_neon_vld2dup:
16036 NewOpc = ARMISD::VLD2DUP_UPD;
16037 NumVecs = 2;
16038 break;
16039 case Intrinsic::arm_neon_vld3dup:
16040 NewOpc = ARMISD::VLD3DUP_UPD;
16041 NumVecs = 3;
16042 break;
16043 case Intrinsic::arm_neon_vld4dup:
16044 NewOpc = ARMISD::VLD4DUP_UPD;
16045 NumVecs = 4;
16046 break;
16047 case Intrinsic::arm_neon_vld2lane:
16048 NewOpc = ARMISD::VLD2LN_UPD;
16049 NumVecs = 2;
16050 isLaneOp = true;
16051 break;
16052 case Intrinsic::arm_neon_vld3lane:
16053 NewOpc = ARMISD::VLD3LN_UPD;
16054 NumVecs = 3;
16055 isLaneOp = true;
16056 break;
16057 case Intrinsic::arm_neon_vld4lane:
16058 NewOpc = ARMISD::VLD4LN_UPD;
16059 NumVecs = 4;
16060 isLaneOp = true;
16061 break;
16062 case Intrinsic::arm_neon_vst1:
16063 NewOpc = ARMISD::VST1_UPD;
16064 NumVecs = 1;
16065 isLoadOp = false;
16066 break;
16067 case Intrinsic::arm_neon_vst2:
16068 NewOpc = ARMISD::VST2_UPD;
16069 NumVecs = 2;
16070 isLoadOp = false;
16071 break;
16072 case Intrinsic::arm_neon_vst3:
16073 NewOpc = ARMISD::VST3_UPD;
16074 NumVecs = 3;
16075 isLoadOp = false;
16076 break;
16077 case Intrinsic::arm_neon_vst4:
16078 NewOpc = ARMISD::VST4_UPD;
16079 NumVecs = 4;
16080 isLoadOp = false;
16081 break;
16082 case Intrinsic::arm_neon_vst2lane:
16083 NewOpc = ARMISD::VST2LN_UPD;
16084 NumVecs = 2;
16085 isLoadOp = false;
16086 isLaneOp = true;
16087 break;
16088 case Intrinsic::arm_neon_vst3lane:
16089 NewOpc = ARMISD::VST3LN_UPD;
16090 NumVecs = 3;
16091 isLoadOp = false;
16092 isLaneOp = true;
16093 break;
16094 case Intrinsic::arm_neon_vst4lane:
16095 NewOpc = ARMISD::VST4LN_UPD;
16096 NumVecs = 4;
16097 isLoadOp = false;
16098 isLaneOp = true;
16099 break;
16100 case Intrinsic::arm_neon_vst1x2:
16101 NewOpc = ARMISD::VST1x2_UPD;
16102 NumVecs = 2;
16103 isLoadOp = false;
16104 hasAlignment = false;
16105 break;
16106 case Intrinsic::arm_neon_vst1x3:
16107 NewOpc = ARMISD::VST1x3_UPD;
16108 NumVecs = 3;
16109 isLoadOp = false;
16110 hasAlignment = false;
16111 break;
16112 case Intrinsic::arm_neon_vst1x4:
16113 NewOpc = ARMISD::VST1x4_UPD;
16114 NumVecs = 4;
16115 isLoadOp = false;
16116 hasAlignment = false;
16117 break;
16118 }
16119 } else {
16120 isLaneOp = true;
16121 switch (N->getOpcode()) {
16122 default:
16123 llvm_unreachable("unexpected opcode for Neon base update");
16124 case ARMISD::VLD1DUP:
16125 NewOpc = ARMISD::VLD1DUP_UPD;
16126 NumVecs = 1;
16127 break;
16128 case ARMISD::VLD2DUP:
16129 NewOpc = ARMISD::VLD2DUP_UPD;
16130 NumVecs = 2;
16131 break;
16132 case ARMISD::VLD3DUP:
16133 NewOpc = ARMISD::VLD3DUP_UPD;
16134 NumVecs = 3;
16135 break;
16136 case ARMISD::VLD4DUP:
16137 NewOpc = ARMISD::VLD4DUP_UPD;
16138 NumVecs = 4;
16139 break;
16140 case ISD::LOAD:
16141 NewOpc = ARMISD::VLD1_UPD;
16142 NumVecs = 1;
16143 isLaneOp = false;
16144 break;
16145 case ISD::STORE:
16146 NewOpc = ARMISD::VST1_UPD;
16147 NumVecs = 1;
16148 isLaneOp = false;
16149 isLoadOp = false;
16150 break;
16151 }
16152 }
16153
16154 // Find the size of memory referenced by the load/store.
16155 EVT VecTy;
16156 if (isLoadOp) {
16157 VecTy = N->getValueType(0);
16158 } else if (Target.isIntrinsic) {
16159 VecTy = N->getOperand(Target.AddrOpIdx + 1).getValueType();
16160 } else {
16161 assert(Target.isStore &&
16162 "Node has to be a load, a store, or an intrinsic!");
16163 VecTy = N->getOperand(1).getValueType();
16164 }
16165
16166 bool isVLDDUPOp =
16167 NewOpc == ARMISD::VLD1DUP_UPD || NewOpc == ARMISD::VLD2DUP_UPD ||
16168 NewOpc == ARMISD::VLD3DUP_UPD || NewOpc == ARMISD::VLD4DUP_UPD;
16169
16170 unsigned NumBytes = NumVecs * VecTy.getSizeInBits() / 8;
16171 if (isLaneOp || isVLDDUPOp)
16172 NumBytes /= VecTy.getVectorNumElements();
16173
16174 if (NumBytes >= 3 * 16 && User.ConstInc != NumBytes) {
16175 // VLD3/4 and VST3/4 for 128-bit vectors are implemented with two
16176 // separate instructions that make it harder to use a non-constant update.
16177 return false;
16178 }
16179
16180 if (SimpleConstIncOnly && User.ConstInc != NumBytes)
16181 return false;
16182
16183 if (!isValidBaseUpdate(N, User.N))
16184 return false;
16185
16186 // OK, we found an ADD we can fold into the base update.
16187 // Now, create a _UPD node, taking care of not breaking alignment.
16188
16189 EVT AlignedVecTy = VecTy;
16190 Align Alignment = MemN->getAlign();
16191
16192 // If this is a less-than-standard-aligned load/store, change the type to
16193 // match the standard alignment.
16194 // The alignment is overlooked when selecting _UPD variants; and it's
16195 // easier to introduce bitcasts here than fix that.
16196 // There are 3 ways to get to this base-update combine:
16197 // - intrinsics: they are assumed to be properly aligned (to the standard
16198 // alignment of the memory type), so we don't need to do anything.
16199 // - ARMISD::VLDx nodes: they are only generated from the aforementioned
16200 // intrinsics, so, likewise, there's nothing to do.
16201 // - generic load/store instructions: the alignment is specified as an
16202 // explicit operand, rather than implicitly as the standard alignment
16203 // of the memory type (like the intrinsics). We need to change the
16204 // memory type to match the explicit alignment. That way, we don't
16205 // generate non-standard-aligned ARMISD::VLDx nodes.
16206 if (isa<LSBaseSDNode>(N)) {
16207 if (Alignment.value() < VecTy.getScalarSizeInBits() / 8) {
16208 MVT EltTy = MVT::getIntegerVT(Alignment.value() * 8);
16209 assert(NumVecs == 1 && "Unexpected multi-element generic load/store.");
16210 assert(!isLaneOp && "Unexpected generic load/store lane.");
16211 unsigned NumElts = NumBytes / (EltTy.getSizeInBits() / 8);
16212 AlignedVecTy = MVT::getVectorVT(EltTy, NumElts);
16213 }
16214 // Don't set an explicit alignment on regular load/stores that we want
16215 // to transform to VLD/VST 1_UPD nodes.
16216 // This matches the behavior of regular load/stores, which only get an
16217 // explicit alignment if the MMO alignment is larger than the standard
16218 // alignment of the memory type.
16219 // Intrinsics, however, always get an explicit alignment, set to the
16220 // alignment of the MMO.
16221 Alignment = Align(1);
16222 }
16223
16224 // Create the new updating load/store node.
16225 // First, create an SDVTList for the new updating node's results.
16226 EVT Tys[6];
16227 unsigned NumResultVecs = (isLoadOp ? NumVecs : 0);
16228 unsigned n;
16229 for (n = 0; n < NumResultVecs; ++n)
16230 Tys[n] = AlignedVecTy;
16231 Tys[n++] = MVT::i32;
16232 Tys[n] = MVT::Other;
16233 SDVTList SDTys = DAG.getVTList(ArrayRef(Tys, NumResultVecs + 2));
16234
16235 // Then, gather the new node's operands.
16237 Ops.push_back(N->getOperand(0)); // incoming chain
16238 Ops.push_back(N->getOperand(Target.AddrOpIdx));
16239 Ops.push_back(User.Inc);
16240
16241 if (StoreSDNode *StN = dyn_cast<StoreSDNode>(N)) {
16242 // Try to match the intrinsic's signature
16243 Ops.push_back(StN->getValue());
16244 } else {
16245 // Loads (and of course intrinsics) match the intrinsics' signature,
16246 // so just add all but the alignment operand.
16247 unsigned LastOperand =
16248 hasAlignment ? N->getNumOperands() - 1 : N->getNumOperands();
16249 for (unsigned i = Target.AddrOpIdx + 1; i < LastOperand; ++i)
16250 Ops.push_back(N->getOperand(i));
16251 }
16252
16253 // For all node types, the alignment operand is always the last one.
16254 Ops.push_back(DAG.getConstant(Alignment.value(), dl, MVT::i32));
16255
16256 // If this is a non-standard-aligned STORE, the penultimate operand is the
16257 // stored value. Bitcast it to the aligned type.
16258 if (AlignedVecTy != VecTy && N->getOpcode() == ISD::STORE) {
16259 SDValue &StVal = Ops[Ops.size() - 2];
16260 StVal = DAG.getNode(ISD::BITCAST, dl, AlignedVecTy, StVal);
16261 }
16262
16263 EVT LoadVT = isLaneOp ? VecTy.getVectorElementType() : AlignedVecTy;
16264 SDValue UpdN = DAG.getMemIntrinsicNode(NewOpc, dl, SDTys, Ops, LoadVT,
16265 MemN->getMemOperand());
16266
16267 // Update the uses.
16268 SmallVector<SDValue, 5> NewResults;
16269 for (unsigned i = 0; i < NumResultVecs; ++i)
16270 NewResults.push_back(SDValue(UpdN.getNode(), i));
16271
16272 // If this is an non-standard-aligned LOAD, the first result is the loaded
16273 // value. Bitcast it to the expected result type.
16274 if (AlignedVecTy != VecTy && N->getOpcode() == ISD::LOAD) {
16275 SDValue &LdVal = NewResults[0];
16276 LdVal = DAG.getNode(ISD::BITCAST, dl, VecTy, LdVal);
16277 }
16278
16279 NewResults.push_back(SDValue(UpdN.getNode(), NumResultVecs + 1)); // chain
16280 DCI.CombineTo(N, NewResults);
16281 DCI.CombineTo(User.N, SDValue(UpdN.getNode(), NumResultVecs));
16282
16283 return true;
16284}
16285
16286// If (opcode ptr inc) is and ADD-like instruction, return the
16287// increment value. Otherwise return 0.
16288static unsigned getPointerConstIncrement(unsigned Opcode, SDValue Ptr,
16289 SDValue Inc, const SelectionDAG &DAG) {
16291 if (!CInc)
16292 return 0;
16293
16294 switch (Opcode) {
16295 case ARMISD::VLD1_UPD:
16296 case ISD::ADD:
16297 return CInc->getZExtValue();
16298 case ISD::OR: {
16299 if (DAG.haveNoCommonBitsSet(Ptr, Inc)) {
16300 // (OR ptr inc) is the same as (ADD ptr inc)
16301 return CInc->getZExtValue();
16302 }
16303 return 0;
16304 }
16305 default:
16306 return 0;
16307 }
16308}
16309
16311 switch (N->getOpcode()) {
16312 case ISD::ADD:
16313 case ISD::OR: {
16314 if (isa<ConstantSDNode>(N->getOperand(1))) {
16315 *Ptr = N->getOperand(0);
16316 *CInc = N->getOperand(1);
16317 return true;
16318 }
16319 return false;
16320 }
16321 case ARMISD::VLD1_UPD: {
16322 if (isa<ConstantSDNode>(N->getOperand(2))) {
16323 *Ptr = N->getOperand(1);
16324 *CInc = N->getOperand(2);
16325 return true;
16326 }
16327 return false;
16328 }
16329 default:
16330 return false;
16331 }
16332}
16333
16334/// CombineBaseUpdate - Target-specific DAG combine function for VLDDUP,
16335/// NEON load/store intrinsics, and generic vector load/stores, to merge
16336/// base address updates.
16337/// For generic load/stores, the memory type is assumed to be a vector.
16338/// The caller is assumed to have checked legality.
16341 const bool isIntrinsic = (N->getOpcode() == ISD::INTRINSIC_VOID ||
16342 N->getOpcode() == ISD::INTRINSIC_W_CHAIN);
16343 const bool isStore = N->getOpcode() == ISD::STORE;
16344 const unsigned AddrOpIdx = ((isIntrinsic || isStore) ? 2 : 1);
16345 BaseUpdateTarget Target = {N, isIntrinsic, isStore, AddrOpIdx};
16346
16347 // Limit the number of possible base-updates we look at to prevent degenerate
16348 // cases.
16349 unsigned MaxBaseUpdates = ArmMaxBaseUpdatesToCheck;
16350
16351 SDValue Addr = N->getOperand(AddrOpIdx);
16352
16354
16355 // Search for a use of the address operand that is an increment.
16356 for (SDUse &Use : Addr->uses()) {
16357 SDNode *User = Use.getUser();
16358 if (Use.getResNo() != Addr.getResNo() || User->getNumOperands() != 2)
16359 continue;
16360
16361 SDValue Inc = User->getOperand(Use.getOperandNo() == 1 ? 0 : 1);
16362 unsigned ConstInc =
16363 getPointerConstIncrement(User->getOpcode(), Addr, Inc, DCI.DAG);
16364
16365 if (ConstInc || User->getOpcode() == ISD::ADD) {
16366 BaseUpdates.push_back({User, Inc, ConstInc});
16367 if (BaseUpdates.size() >= MaxBaseUpdates)
16368 break;
16369 }
16370 }
16371
16372 // If the address is a constant pointer increment itself, find
16373 // another constant increment that has the same base operand
16374 SDValue Base;
16375 SDValue CInc;
16376 if (findPointerConstIncrement(Addr.getNode(), &Base, &CInc)) {
16377 unsigned Offset =
16378 getPointerConstIncrement(Addr->getOpcode(), Base, CInc, DCI.DAG);
16379 if (Offset) {
16380 for (SDUse &Use : Base->uses()) {
16381
16382 SDNode *User = Use.getUser();
16383 if (Use.getResNo() != Base.getResNo() || User == Addr.getNode() ||
16384 User->getNumOperands() != 2)
16385 continue;
16386
16387 SDValue UserInc = User->getOperand(Use.getOperandNo() == 0 ? 1 : 0);
16388 unsigned UserOffset =
16389 getPointerConstIncrement(User->getOpcode(), Base, UserInc, DCI.DAG);
16390
16391 if (!UserOffset || UserOffset <= Offset)
16392 continue;
16393
16394 unsigned NewConstInc = UserOffset - Offset;
16395 SDValue NewInc = DCI.DAG.getConstant(NewConstInc, SDLoc(N), MVT::i32);
16396 BaseUpdates.push_back({User, NewInc, NewConstInc});
16397 if (BaseUpdates.size() >= MaxBaseUpdates)
16398 break;
16399 }
16400 }
16401 }
16402
16403 // Try to fold the load/store with an update that matches memory
16404 // access size. This should work well for sequential loads.
16405 unsigned NumValidUpd = BaseUpdates.size();
16406 for (unsigned I = 0; I < NumValidUpd; I++) {
16407 BaseUpdateUser &User = BaseUpdates[I];
16408 if (TryCombineBaseUpdate(Target, User, /*SimpleConstIncOnly=*/true, DCI))
16409 return SDValue();
16410 }
16411
16412 // Try to fold with other users. Non-constant updates are considered
16413 // first, and constant updates are sorted to not break a sequence of
16414 // strided accesses (if there is any).
16415 llvm::stable_sort(BaseUpdates,
16416 [](const BaseUpdateUser &LHS, const BaseUpdateUser &RHS) {
16417 return LHS.ConstInc < RHS.ConstInc;
16418 });
16419 for (BaseUpdateUser &User : BaseUpdates) {
16420 if (TryCombineBaseUpdate(Target, User, /*SimpleConstIncOnly=*/false, DCI))
16421 return SDValue();
16422 }
16423 return SDValue();
16424}
16425
16428 if (DCI.isBeforeLegalize() || DCI.isCalledByLegalizer())
16429 return SDValue();
16430
16431 return CombineBaseUpdate(N, DCI);
16432}
16433
16436 if (DCI.isBeforeLegalize() || DCI.isCalledByLegalizer())
16437 return SDValue();
16438
16439 SelectionDAG &DAG = DCI.DAG;
16440 SDValue Addr = N->getOperand(2);
16441 MemSDNode *MemN = cast<MemSDNode>(N);
16442 SDLoc dl(N);
16443
16444 // For the stores, where there are multiple intrinsics we only actually want
16445 // to post-inc the last of the them.
16446 unsigned IntNo = N->getConstantOperandVal(1);
16447 if (IntNo == Intrinsic::arm_mve_vst2q && N->getConstantOperandVal(5) != 1)
16448 return SDValue();
16449 if (IntNo == Intrinsic::arm_mve_vst4q && N->getConstantOperandVal(7) != 3)
16450 return SDValue();
16451
16452 // Search for a use of the address operand that is an increment.
16453 for (SDUse &Use : Addr->uses()) {
16454 SDNode *User = Use.getUser();
16455 if (User->getOpcode() != ISD::ADD || Use.getResNo() != Addr.getResNo())
16456 continue;
16457
16458 // Check that the add is independent of the load/store. Otherwise, folding
16459 // it would create a cycle. We can avoid searching through Addr as it's a
16460 // predecessor to both.
16463 Visited.insert(Addr.getNode());
16464 Worklist.push_back(N);
16465 Worklist.push_back(User);
16466 const unsigned MaxSteps = 1024;
16467 if (SDNode::hasPredecessorHelper(N, Visited, Worklist, MaxSteps) ||
16468 SDNode::hasPredecessorHelper(User, Visited, Worklist, MaxSteps))
16469 continue;
16470
16471 // Find the new opcode for the updating load/store.
16472 bool isLoadOp = true;
16473 unsigned NewOpc = 0;
16474 unsigned NumVecs = 0;
16475 switch (IntNo) {
16476 default:
16477 llvm_unreachable("unexpected intrinsic for MVE VLDn combine");
16478 case Intrinsic::arm_mve_vld2q:
16479 NewOpc = ARMISD::VLD2_UPD;
16480 NumVecs = 2;
16481 break;
16482 case Intrinsic::arm_mve_vld4q:
16483 NewOpc = ARMISD::VLD4_UPD;
16484 NumVecs = 4;
16485 break;
16486 case Intrinsic::arm_mve_vst2q:
16487 NewOpc = ARMISD::VST2_UPD;
16488 NumVecs = 2;
16489 isLoadOp = false;
16490 break;
16491 case Intrinsic::arm_mve_vst4q:
16492 NewOpc = ARMISD::VST4_UPD;
16493 NumVecs = 4;
16494 isLoadOp = false;
16495 break;
16496 }
16497
16498 // Find the size of memory referenced by the load/store.
16499 EVT VecTy;
16500 if (isLoadOp) {
16501 VecTy = N->getValueType(0);
16502 } else {
16503 VecTy = N->getOperand(3).getValueType();
16504 }
16505
16506 unsigned NumBytes = NumVecs * VecTy.getSizeInBits() / 8;
16507
16508 // If the increment is a constant, it must match the memory ref size.
16509 SDValue Inc = User->getOperand(User->getOperand(0) == Addr ? 1 : 0);
16511 if (!CInc || CInc->getZExtValue() != NumBytes)
16512 continue;
16513
16514 // Create the new updating load/store node.
16515 // First, create an SDVTList for the new updating node's results.
16516 EVT Tys[6];
16517 unsigned NumResultVecs = (isLoadOp ? NumVecs : 0);
16518 unsigned n;
16519 for (n = 0; n < NumResultVecs; ++n)
16520 Tys[n] = VecTy;
16521 Tys[n++] = MVT::i32;
16522 Tys[n] = MVT::Other;
16523 SDVTList SDTys = DAG.getVTList(ArrayRef(Tys, NumResultVecs + 2));
16524
16525 // Then, gather the new node's operands.
16527 Ops.push_back(N->getOperand(0)); // incoming chain
16528 Ops.push_back(N->getOperand(2)); // ptr
16529 Ops.push_back(Inc);
16530
16531 for (unsigned i = 3; i < N->getNumOperands(); ++i)
16532 Ops.push_back(N->getOperand(i));
16533
16534 SDValue UpdN = DAG.getMemIntrinsicNode(NewOpc, dl, SDTys, Ops, VecTy,
16535 MemN->getMemOperand());
16536
16537 // Update the uses.
16538 SmallVector<SDValue, 5> NewResults;
16539 for (unsigned i = 0; i < NumResultVecs; ++i)
16540 NewResults.push_back(SDValue(UpdN.getNode(), i));
16541
16542 NewResults.push_back(SDValue(UpdN.getNode(), NumResultVecs + 1)); // chain
16543 DCI.CombineTo(N, NewResults);
16544 DCI.CombineTo(User, SDValue(UpdN.getNode(), NumResultVecs));
16545
16546 break;
16547 }
16548
16549 return SDValue();
16550}
16551
16552/// CombineVLDDUP - For a VDUPLANE node N, check if its source operand is a
16553/// vldN-lane (N > 1) intrinsic, and if all the other uses of that intrinsic
16554/// are also VDUPLANEs. If so, combine them to a vldN-dup operation and
16555/// return true.
16557 SelectionDAG &DAG = DCI.DAG;
16558 EVT VT = N->getValueType(0);
16559 // vldN-dup instructions only support 64-bit vectors for N > 1.
16560 if (!VT.is64BitVector())
16561 return false;
16562
16563 // Check if the VDUPLANE operand is a vldN-dup intrinsic.
16564 SDNode *VLD = N->getOperand(0).getNode();
16565 if (VLD->getOpcode() != ISD::INTRINSIC_W_CHAIN)
16566 return false;
16567 unsigned NumVecs = 0;
16568 unsigned NewOpc = 0;
16569 unsigned IntNo = VLD->getConstantOperandVal(1);
16570 if (IntNo == Intrinsic::arm_neon_vld2lane) {
16571 NumVecs = 2;
16572 NewOpc = ARMISD::VLD2DUP;
16573 } else if (IntNo == Intrinsic::arm_neon_vld3lane) {
16574 NumVecs = 3;
16575 NewOpc = ARMISD::VLD3DUP;
16576 } else if (IntNo == Intrinsic::arm_neon_vld4lane) {
16577 NumVecs = 4;
16578 NewOpc = ARMISD::VLD4DUP;
16579 } else {
16580 return false;
16581 }
16582
16583 // First check that all the vldN-lane uses are VDUPLANEs and that the lane
16584 // numbers match the load.
16585 unsigned VLDLaneNo = VLD->getConstantOperandVal(NumVecs + 3);
16586 for (SDUse &Use : VLD->uses()) {
16587 // Ignore uses of the chain result.
16588 if (Use.getResNo() == NumVecs)
16589 continue;
16590 SDNode *User = Use.getUser();
16591 if (User->getOpcode() != ARMISD::VDUPLANE ||
16592 VLDLaneNo != User->getConstantOperandVal(1))
16593 return false;
16594 }
16595
16596 // Create the vldN-dup node.
16597 EVT Tys[5];
16598 unsigned n;
16599 for (n = 0; n < NumVecs; ++n)
16600 Tys[n] = VT;
16601 Tys[n] = MVT::Other;
16602 SDVTList SDTys = DAG.getVTList(ArrayRef(Tys, NumVecs + 1));
16603 SDValue Ops[] = { VLD->getOperand(0), VLD->getOperand(2) };
16605 SDValue VLDDup = DAG.getMemIntrinsicNode(NewOpc, SDLoc(VLD), SDTys,
16606 Ops, VLDMemInt->getMemoryVT(),
16607 VLDMemInt->getMemOperand());
16608
16609 // Update the uses.
16610 for (SDUse &Use : VLD->uses()) {
16611 unsigned ResNo = Use.getResNo();
16612 // Ignore uses of the chain result.
16613 if (ResNo == NumVecs)
16614 continue;
16615 DCI.CombineTo(Use.getUser(), SDValue(VLDDup.getNode(), ResNo));
16616 }
16617
16618 // Now the vldN-lane intrinsic is dead except for its chain result.
16619 // Update uses of the chain.
16620 std::vector<SDValue> VLDDupResults;
16621 for (unsigned n = 0; n < NumVecs; ++n)
16622 VLDDupResults.push_back(SDValue(VLDDup.getNode(), n));
16623 VLDDupResults.push_back(SDValue(VLDDup.getNode(), NumVecs));
16624 DCI.CombineTo(VLD, VLDDupResults);
16625
16626 return true;
16627}
16628
16629/// PerformVDUPLANECombine - Target-specific dag combine xforms for
16630/// ARMISD::VDUPLANE.
16633 const ARMSubtarget *Subtarget) {
16634 SDValue Op = N->getOperand(0);
16635 EVT VT = N->getValueType(0);
16636
16637 // On MVE, we just convert the VDUPLANE to a VDUP with an extract.
16638 if (Subtarget->hasMVEIntegerOps()) {
16639 EVT ExtractVT = VT.getVectorElementType();
16640 // We need to ensure we are creating a legal type.
16641 if (!DCI.DAG.getTargetLoweringInfo().isTypeLegal(ExtractVT))
16642 ExtractVT = MVT::i32;
16643 SDValue Extract = DCI.DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SDLoc(N), ExtractVT,
16644 N->getOperand(0), N->getOperand(1));
16645 return DCI.DAG.getNode(ARMISD::VDUP, SDLoc(N), VT, Extract);
16646 }
16647
16648 // If the source is a vldN-lane (N > 1) intrinsic, and all the other uses
16649 // of that intrinsic are also VDUPLANEs, combine them to a vldN-dup operation.
16650 if (CombineVLDDUP(N, DCI))
16651 return SDValue(N, 0);
16652
16653 // If the source is already a VMOVIMM or VMVNIMM splat, the VDUPLANE is
16654 // redundant. Ignore bit_converts for now; element sizes are checked below.
16655 while (Op.getOpcode() == ISD::BITCAST)
16656 Op = Op.getOperand(0);
16657 if (Op.getOpcode() != ARMISD::VMOVIMM && Op.getOpcode() != ARMISD::VMVNIMM)
16658 return SDValue();
16659
16660 // Make sure the VMOV element size is not bigger than the VDUPLANE elements.
16661 unsigned EltSize = Op.getScalarValueSizeInBits();
16662 // The canonical VMOV for a zero vector uses a 32-bit element size.
16663 unsigned Imm = Op.getConstantOperandVal(0);
16664 unsigned EltBits;
16665 if (ARM_AM::decodeVMOVModImm(Imm, EltBits) == 0)
16666 EltSize = 8;
16667 if (EltSize > VT.getScalarSizeInBits())
16668 return SDValue();
16669
16670 return DCI.DAG.getNode(ISD::BITCAST, SDLoc(N), VT, Op);
16671}
16672
16673/// PerformVDUPCombine - Target-specific dag combine xforms for ARMISD::VDUP.
16675 const ARMSubtarget *Subtarget) {
16676 SDValue Op = N->getOperand(0);
16677 SDLoc dl(N);
16678
16679 if (Subtarget->hasMVEIntegerOps()) {
16680 // Convert VDUP f32 -> VDUP BITCAST i32 under MVE, as we know the value will
16681 // need to come from a GPR.
16682 if (Op.getValueType() == MVT::f32)
16683 return DAG.getNode(ARMISD::VDUP, dl, N->getValueType(0),
16684 DAG.getNode(ISD::BITCAST, dl, MVT::i32, Op));
16685 else if (Op.getValueType() == MVT::f16)
16686 return DAG.getNode(ARMISD::VDUP, dl, N->getValueType(0),
16687 DAG.getNode(ARMISD::VMOVrh, dl, MVT::i32, Op));
16688 }
16689
16690 if (!Subtarget->hasNEON())
16691 return SDValue();
16692
16693 // Match VDUP(LOAD) -> VLD1DUP.
16694 // We match this pattern here rather than waiting for isel because the
16695 // transform is only legal for unindexed loads.
16696 LoadSDNode *LD = dyn_cast<LoadSDNode>(Op.getNode());
16697 if (LD && Op.hasOneUse() && LD->isUnindexed() &&
16698 LD->getMemoryVT() == N->getValueType(0).getVectorElementType()) {
16699 SDValue Ops[] = {LD->getOperand(0), LD->getOperand(1),
16700 DAG.getConstant(LD->getAlign().value(), SDLoc(N), MVT::i32)};
16701 SDVTList SDTys = DAG.getVTList(N->getValueType(0), MVT::Other);
16702 SDValue VLDDup =
16704 LD->getMemoryVT(), LD->getMemOperand());
16705 DAG.ReplaceAllUsesOfValueWith(SDValue(LD, 1), VLDDup.getValue(1));
16706 return VLDDup;
16707 }
16708
16709 return SDValue();
16710}
16711
16714 const ARMSubtarget *Subtarget) {
16715 EVT VT = N->getValueType(0);
16716
16717 // If this is a legal vector load, try to combine it into a VLD1_UPD.
16718 if (Subtarget->hasNEON() && ISD::isNormalLoad(N) && VT.isVector() &&
16720 return CombineBaseUpdate(N, DCI);
16721
16722 return SDValue();
16723}
16724
16725// Optimize trunc store (of multiple scalars) to shuffle and store. First,
16726// pack all of the elements in one place. Next, store to memory in fewer
16727// chunks.
16729 SelectionDAG &DAG) {
16730 SDValue StVal = St->getValue();
16731 EVT VT = StVal.getValueType();
16732 if (!St->isTruncatingStore() || !VT.isVector())
16733 return SDValue();
16734 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
16735 EVT StVT = St->getMemoryVT();
16736 unsigned NumElems = VT.getVectorNumElements();
16737 assert(StVT != VT && "Cannot truncate to the same type");
16738 unsigned FromEltSz = VT.getScalarSizeInBits();
16739 unsigned ToEltSz = StVT.getScalarSizeInBits();
16740
16741 // From, To sizes and ElemCount must be pow of two
16742 if (!isPowerOf2_32(NumElems * FromEltSz * ToEltSz))
16743 return SDValue();
16744
16745 // We are going to use the original vector elt for storing.
16746 // Accumulated smaller vector elements must be a multiple of the store size.
16747 if (0 != (NumElems * FromEltSz) % ToEltSz)
16748 return SDValue();
16749
16750 unsigned SizeRatio = FromEltSz / ToEltSz;
16751 assert(SizeRatio * NumElems * ToEltSz == VT.getSizeInBits());
16752
16753 // Create a type on which we perform the shuffle.
16754 EVT WideVecVT = EVT::getVectorVT(*DAG.getContext(), StVT.getScalarType(),
16755 NumElems * SizeRatio);
16756 assert(WideVecVT.getSizeInBits() == VT.getSizeInBits());
16757
16758 SDLoc DL(St);
16759 SDValue WideVec = DAG.getNode(ISD::BITCAST, DL, WideVecVT, StVal);
16760 SmallVector<int, 8> ShuffleVec(NumElems * SizeRatio, -1);
16761 for (unsigned i = 0; i < NumElems; ++i)
16762 ShuffleVec[i] = DAG.getDataLayout().isBigEndian() ? (i + 1) * SizeRatio - 1
16763 : i * SizeRatio;
16764
16765 // Can't shuffle using an illegal type.
16766 if (!TLI.isTypeLegal(WideVecVT))
16767 return SDValue();
16768
16769 SDValue Shuff = DAG.getVectorShuffle(
16770 WideVecVT, DL, WideVec, DAG.getUNDEF(WideVec.getValueType()), ShuffleVec);
16771 // At this point all of the data is stored at the bottom of the
16772 // register. We now need to save it to mem.
16773
16774 // Find the largest store unit
16775 MVT StoreType = MVT::i8;
16776 for (MVT Tp : MVT::integer_valuetypes()) {
16777 if (TLI.isTypeLegal(Tp) && Tp.getSizeInBits() <= NumElems * ToEltSz)
16778 StoreType = Tp;
16779 }
16780 // Didn't find a legal store type.
16781 if (!TLI.isTypeLegal(StoreType))
16782 return SDValue();
16783
16784 // Bitcast the original vector into a vector of store-size units
16785 EVT StoreVecVT =
16786 EVT::getVectorVT(*DAG.getContext(), StoreType,
16787 VT.getSizeInBits() / EVT(StoreType).getSizeInBits());
16788 assert(StoreVecVT.getSizeInBits() == VT.getSizeInBits());
16789 SDValue ShuffWide = DAG.getNode(ISD::BITCAST, DL, StoreVecVT, Shuff);
16791 SDValue Increment = DAG.getConstant(StoreType.getSizeInBits() / 8, DL,
16792 TLI.getPointerTy(DAG.getDataLayout()));
16793 SDValue BasePtr = St->getBasePtr();
16794
16795 // Perform one or more big stores into memory.
16796 unsigned E = (ToEltSz * NumElems) / StoreType.getSizeInBits();
16797 for (unsigned I = 0; I < E; I++) {
16798 SDValue SubVec = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, StoreType,
16799 ShuffWide, DAG.getIntPtrConstant(I, DL));
16800 SDValue Ch =
16801 DAG.getStore(St->getChain(), DL, SubVec, BasePtr, St->getPointerInfo(),
16802 St->getAlign(), St->getMemOperand()->getFlags());
16803 BasePtr =
16804 DAG.getNode(ISD::ADD, DL, BasePtr.getValueType(), BasePtr, Increment);
16805 Chains.push_back(Ch);
16806 }
16807 return DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Chains);
16808}
16809
16810// Try taking a single vector store from an fpround (which would otherwise turn
16811// into an expensive buildvector) and splitting it into a series of narrowing
16812// stores.
16814 SelectionDAG &DAG) {
16815 if (!St->isSimple() || St->isTruncatingStore() || !St->isUnindexed())
16816 return SDValue();
16817 SDValue Trunc = St->getValue();
16818 if (Trunc->getOpcode() != ISD::FP_ROUND)
16819 return SDValue();
16820 EVT FromVT = Trunc->getOperand(0).getValueType();
16821 EVT ToVT = Trunc.getValueType();
16822 if (!ToVT.isVector())
16823 return SDValue();
16825 EVT ToEltVT = ToVT.getVectorElementType();
16826 EVT FromEltVT = FromVT.getVectorElementType();
16827
16828 if (FromEltVT != MVT::f32 || ToEltVT != MVT::f16)
16829 return SDValue();
16830
16831 unsigned NumElements = 4;
16832 if (FromVT.getVectorNumElements() % NumElements != 0)
16833 return SDValue();
16834
16835 // Test if the Trunc will be convertible to a VMOVN with a shuffle, and if so
16836 // use the VMOVN over splitting the store. We are looking for patterns of:
16837 // !rev: 0 N 1 N+1 2 N+2 ...
16838 // rev: N 0 N+1 1 N+2 2 ...
16839 // The shuffle may either be a single source (in which case N = NumElts/2) or
16840 // two inputs extended with concat to the same size (in which case N =
16841 // NumElts).
16842 auto isVMOVNShuffle = [&](ShuffleVectorSDNode *SVN, bool Rev) {
16843 ArrayRef<int> M = SVN->getMask();
16844 unsigned NumElts = ToVT.getVectorNumElements();
16845 if (SVN->getOperand(1).isUndef())
16846 NumElts /= 2;
16847
16848 unsigned Off0 = Rev ? NumElts : 0;
16849 unsigned Off1 = Rev ? 0 : NumElts;
16850
16851 for (unsigned I = 0; I < NumElts; I += 2) {
16852 if (M[I] >= 0 && M[I] != (int)(Off0 + I / 2))
16853 return false;
16854 if (M[I + 1] >= 0 && M[I + 1] != (int)(Off1 + I / 2))
16855 return false;
16856 }
16857
16858 return true;
16859 };
16860
16861 if (auto *Shuffle = dyn_cast<ShuffleVectorSDNode>(Trunc.getOperand(0)))
16862 if (isVMOVNShuffle(Shuffle, false) || isVMOVNShuffle(Shuffle, true))
16863 return SDValue();
16864
16865 LLVMContext &C = *DAG.getContext();
16866 SDLoc DL(St);
16867 // Details about the old store
16868 SDValue Ch = St->getChain();
16869 SDValue BasePtr = St->getBasePtr();
16870 Align Alignment = St->getBaseAlign();
16871 MachineMemOperand::Flags MMOFlags = St->getMemOperand()->getFlags();
16872 AAMDNodes AAInfo = St->getAAInfo();
16873
16874 // We split the store into slices of NumElements. fp16 trunc stores are vcvt
16875 // and then stored as truncating integer stores.
16876 EVT NewFromVT = EVT::getVectorVT(C, FromEltVT, NumElements);
16877 EVT NewToVT = EVT::getVectorVT(
16878 C, EVT::getIntegerVT(C, ToEltVT.getSizeInBits()), NumElements);
16879
16881 for (unsigned i = 0; i < FromVT.getVectorNumElements() / NumElements; i++) {
16882 unsigned NewOffset = i * NumElements * ToEltVT.getSizeInBits() / 8;
16883 SDValue NewPtr =
16884 DAG.getObjectPtrOffset(DL, BasePtr, TypeSize::getFixed(NewOffset));
16885
16886 SDValue Extract =
16887 DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, NewFromVT, Trunc.getOperand(0),
16888 DAG.getConstant(i * NumElements, DL, MVT::i32));
16889
16890 SDValue FPTrunc =
16891 DAG.getNode(ARMISD::VCVTN, DL, MVT::v8f16, DAG.getUNDEF(MVT::v8f16),
16892 Extract, DAG.getConstant(0, DL, MVT::i32));
16893 Extract = DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, MVT::v4i32, FPTrunc);
16894
16896 Ch, DL, Extract, NewPtr, St->getPointerInfo().getWithOffset(NewOffset),
16897 NewToVT, Alignment, MMOFlags, AAInfo);
16898 Stores.push_back(Store);
16899 }
16900 return DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Stores);
16901}
16902
16903// Try taking a single vector store from an MVETRUNC (which would otherwise turn
16904// into an expensive buildvector) and splitting it into a series of narrowing
16905// stores.
16907 SelectionDAG &DAG) {
16908 if (!St->isSimple() || St->isTruncatingStore() || !St->isUnindexed())
16909 return SDValue();
16910 SDValue Trunc = St->getValue();
16911 if (Trunc->getOpcode() != ARMISD::MVETRUNC)
16912 return SDValue();
16913 EVT FromVT = Trunc->getOperand(0).getValueType();
16914 EVT ToVT = Trunc.getValueType();
16915
16916 LLVMContext &C = *DAG.getContext();
16917 SDLoc DL(St);
16918 // Details about the old store
16919 SDValue Ch = St->getChain();
16920 SDValue BasePtr = St->getBasePtr();
16921 Align Alignment = St->getBaseAlign();
16922 MachineMemOperand::Flags MMOFlags = St->getMemOperand()->getFlags();
16923 AAMDNodes AAInfo = St->getAAInfo();
16924
16925 EVT NewToVT = EVT::getVectorVT(C, ToVT.getVectorElementType(),
16926 FromVT.getVectorNumElements());
16927
16929 for (unsigned i = 0; i < Trunc.getNumOperands(); i++) {
16930 unsigned NewOffset =
16931 i * FromVT.getVectorNumElements() * ToVT.getScalarSizeInBits() / 8;
16932 SDValue NewPtr =
16933 DAG.getObjectPtrOffset(DL, BasePtr, TypeSize::getFixed(NewOffset));
16934
16935 SDValue Extract = Trunc.getOperand(i);
16937 Ch, DL, Extract, NewPtr, St->getPointerInfo().getWithOffset(NewOffset),
16938 NewToVT, Alignment, MMOFlags, AAInfo);
16939 Stores.push_back(Store);
16940 }
16941 return DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Stores);
16942}
16943
16944// Given a floating point store from an extracted vector, with an integer
16945// VGETLANE that already exists, store the existing VGETLANEu directly. This can
16946// help reduce fp register pressure, doesn't require the fp extract and allows
16947// use of more integer post-inc stores not available with vstr.
16949 if (!St->isSimple() || St->isTruncatingStore() || !St->isUnindexed())
16950 return SDValue();
16951 SDValue Extract = St->getValue();
16952 EVT VT = Extract.getValueType();
16953 // For now only uses f16. This may be useful for f32 too, but that will
16954 // be bitcast(extract), not the VGETLANEu we currently check here.
16955 if (VT != MVT::f16 || Extract->getOpcode() != ISD::EXTRACT_VECTOR_ELT)
16956 return SDValue();
16957
16958 SDNode *GetLane =
16959 DAG.getNodeIfExists(ARMISD::VGETLANEu, DAG.getVTList(MVT::i32),
16960 {Extract.getOperand(0), Extract.getOperand(1)});
16961 if (!GetLane)
16962 return SDValue();
16963
16964 LLVMContext &C = *DAG.getContext();
16965 SDLoc DL(St);
16966 // Create a new integer store to replace the existing floating point version.
16967 SDValue Ch = St->getChain();
16968 SDValue BasePtr = St->getBasePtr();
16969 Align Alignment = St->getBaseAlign();
16970 MachineMemOperand::Flags MMOFlags = St->getMemOperand()->getFlags();
16971 AAMDNodes AAInfo = St->getAAInfo();
16972 EVT NewToVT = EVT::getIntegerVT(C, VT.getSizeInBits());
16973 SDValue Store = DAG.getTruncStore(Ch, DL, SDValue(GetLane, 0), BasePtr,
16974 St->getPointerInfo(), NewToVT, Alignment,
16975 MMOFlags, AAInfo);
16976
16977 return Store;
16978}
16979
16980/// PerformSTORECombine - Target-specific dag combine xforms for
16981/// ISD::STORE.
16984 const ARMSubtarget *Subtarget) {
16986 if (St->isVolatile())
16987 return SDValue();
16988 SDValue StVal = St->getValue();
16989 EVT VT = StVal.getValueType();
16990
16991 if (Subtarget->hasNEON())
16993 return Store;
16994
16995 if (Subtarget->hasMVEFloatOps())
16996 if (SDValue NewToken = PerformSplittingToNarrowingStores(St, DCI.DAG))
16997 return NewToken;
16998
16999 if (Subtarget->hasMVEIntegerOps()) {
17000 if (SDValue NewChain = PerformExtractFpToIntStores(St, DCI.DAG))
17001 return NewChain;
17002 if (SDValue NewToken =
17004 return NewToken;
17005 }
17006
17007 if (!ISD::isNormalStore(St))
17008 return SDValue();
17009
17010 // Split a store of a VMOVDRR into two integer stores to avoid mixing NEON and
17011 // ARM stores of arguments in the same cache line.
17012 if (StVal.getOpcode() == ARMISD::VMOVDRR && StVal->hasOneUse()) {
17013 SelectionDAG &DAG = DCI.DAG;
17014 bool isBigEndian = DAG.getDataLayout().isBigEndian();
17015 SDLoc DL(St);
17016 SDValue BasePtr = St->getBasePtr();
17017 SDValue NewST1 =
17018 DAG.getStore(St->getChain(), DL, StVal.getOperand(isBigEndian ? 1 : 0),
17019 BasePtr, St->getPointerInfo(), St->getBaseAlign(),
17020 St->getMemOperand()->getFlags());
17021
17022 SDValue OffsetPtr = DAG.getNode(ISD::ADD, DL, MVT::i32, BasePtr,
17023 DAG.getConstant(4, DL, MVT::i32));
17024 return DAG.getStore(NewST1.getValue(0), DL,
17025 StVal.getOperand(isBigEndian ? 0 : 1), OffsetPtr,
17026 St->getPointerInfo().getWithOffset(4),
17027 St->getBaseAlign(), St->getMemOperand()->getFlags());
17028 }
17029
17030 if (StVal.getValueType() == MVT::i64 &&
17032 // Bitcast an i64 store extracted from a vector to f64.
17033 // Otherwise, the i64 value will be legalized to a pair of i32 values.
17034 SelectionDAG &DAG = DCI.DAG;
17035 SDLoc dl(StVal);
17036 SDValue IntVec = StVal.getOperand(0);
17037 EVT FloatVT =
17038 EVT::getVectorVT(*DAG.getContext(), MVT::f64,
17040 SDValue Vec = DAG.getNode(ISD::BITCAST, dl, FloatVT, IntVec);
17041 SDValue ExtElt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f64, Vec,
17042 StVal.getOperand(1));
17043 dl = SDLoc(N);
17044 SDValue V = DAG.getNode(ISD::BITCAST, dl, MVT::i64, ExtElt);
17045 // Make the DAGCombiner fold the bitcasts.
17046 DCI.AddToWorklist(Vec.getNode());
17047 DCI.AddToWorklist(ExtElt.getNode());
17048 DCI.AddToWorklist(V.getNode());
17049 return DAG.getStore(St->getChain(), dl, V, St->getBasePtr(),
17050 St->getPointerInfo(), St->getAlign(),
17051 St->getMemOperand()->getFlags(), St->getAAInfo());
17052 }
17053
17054 // If this is a legal vector store, try to combine it into a VST1_UPD.
17055 if (Subtarget->hasNEON() && ISD::isNormalStore(N) && VT.isVector() &&
17057 return CombineBaseUpdate(N, DCI);
17058
17059 return SDValue();
17060}
17061
17062/// PerformVCVTCombine - VCVT (floating-point to fixed-point, Advanced SIMD)
17063/// can replace combinations of VMUL and VCVT (floating-point to integer)
17064/// when the VMUL has a constant operand that is a power of 2.
17065///
17066/// Example (assume d17 = <float 8.000000e+00, float 8.000000e+00>):
17067/// vmul.f32 d16, d17, d16
17068/// vcvt.s32.f32 d16, d16
17069/// becomes:
17070/// vcvt.s32.f32 d16, d16, #3
17072 const ARMSubtarget *Subtarget) {
17073 if (!Subtarget->hasNEON())
17074 return SDValue();
17075
17076 SDValue Op = N->getOperand(0);
17077 if (!Op.getValueType().isVector() || !Op.getValueType().isSimple() ||
17078 Op.getOpcode() != ISD::FMUL)
17079 return SDValue();
17080
17081 SDValue ConstVec = Op->getOperand(1);
17082 if (!isa<BuildVectorSDNode>(ConstVec))
17083 return SDValue();
17084
17085 MVT FloatTy = Op.getSimpleValueType().getVectorElementType();
17086 uint32_t FloatBits = FloatTy.getSizeInBits();
17087 MVT IntTy = N->getSimpleValueType(0).getVectorElementType();
17088 uint32_t IntBits = IntTy.getSizeInBits();
17089 unsigned NumLanes = Op.getValueType().getVectorNumElements();
17090 if (FloatBits != 32 || IntBits > 32 || (NumLanes != 4 && NumLanes != 2)) {
17091 // These instructions only exist converting from f32 to i32. We can handle
17092 // smaller integers by generating an extra truncate, but larger ones would
17093 // be lossy. We also can't handle anything other than 2 or 4 lanes, since
17094 // these instructions only support v2i32/v4i32 types.
17095 return SDValue();
17096 }
17097
17098 BitVector UndefElements;
17100 int32_t C = BV->getConstantFPSplatPow2ToLog2Int(&UndefElements, 33);
17101 if (C == -1 || C == 0 || C > 32)
17102 return SDValue();
17103
17104 SDLoc dl(N);
17105 bool isSigned = N->getOpcode() == ISD::FP_TO_SINT;
17106 unsigned IntrinsicOpcode = isSigned ? Intrinsic::arm_neon_vcvtfp2fxs :
17107 Intrinsic::arm_neon_vcvtfp2fxu;
17108 SDValue FixConv = DAG.getNode(
17109 ISD::INTRINSIC_WO_CHAIN, dl, NumLanes == 2 ? MVT::v2i32 : MVT::v4i32,
17110 DAG.getConstant(IntrinsicOpcode, dl, MVT::i32), Op->getOperand(0),
17111 DAG.getConstant(C, dl, MVT::i32));
17112
17113 if (IntBits < FloatBits)
17114 FixConv = DAG.getNode(ISD::TRUNCATE, dl, N->getValueType(0), FixConv);
17115
17116 return FixConv;
17117}
17118
17120 const ARMSubtarget *Subtarget) {
17121 if (!Subtarget->hasMVEFloatOps())
17122 return SDValue();
17123
17124 // Turn (fadd x, (vselect c, y, -0.0)) into (vselect c, (fadd x, y), x)
17125 // The second form can be more easily turned into a predicated vadd, and
17126 // possibly combined into a fma to become a predicated vfma.
17127 SDValue Op0 = N->getOperand(0);
17128 SDValue Op1 = N->getOperand(1);
17129 EVT VT = N->getValueType(0);
17130 SDLoc DL(N);
17131
17132 // The identity element for a fadd is -0.0 or +0.0 when the nsz flag is set,
17133 // which these VMOV's represent.
17134 auto isIdentitySplat = [&](SDValue Op, bool NSZ) {
17135 if (Op.getOpcode() != ISD::BITCAST ||
17136 Op.getOperand(0).getOpcode() != ARMISD::VMOVIMM)
17137 return false;
17138 uint64_t ImmVal = Op.getOperand(0).getConstantOperandVal(0);
17139 if (VT == MVT::v4f32 && (ImmVal == 1664 || (ImmVal == 0 && NSZ)))
17140 return true;
17141 if (VT == MVT::v8f16 && (ImmVal == 2688 || (ImmVal == 0 && NSZ)))
17142 return true;
17143 return false;
17144 };
17145
17146 if (Op0.getOpcode() == ISD::VSELECT && Op1.getOpcode() != ISD::VSELECT)
17147 std::swap(Op0, Op1);
17148
17149 if (Op1.getOpcode() != ISD::VSELECT)
17150 return SDValue();
17151
17152 SDNodeFlags FaddFlags = N->getFlags();
17153 bool NSZ = FaddFlags.hasNoSignedZeros();
17154 if (!isIdentitySplat(Op1.getOperand(2), NSZ))
17155 return SDValue();
17156
17157 SDValue FAdd =
17158 DAG.getNode(ISD::FADD, DL, VT, Op0, Op1.getOperand(1), FaddFlags);
17159 return DAG.getNode(ISD::VSELECT, DL, VT, Op1.getOperand(0), FAdd, Op0, FaddFlags);
17160}
17161
17163 SDValue LHS = N->getOperand(0);
17164 SDValue RHS = N->getOperand(1);
17165 EVT VT = N->getValueType(0);
17166 SDLoc DL(N);
17167
17168 if (!N->getFlags().hasAllowReassociation())
17169 return SDValue();
17170
17171 // Combine fadd(a, vcmla(b, c, d)) -> vcmla(fadd(a, b), b, c)
17172 auto ReassocComplex = [&](SDValue A, SDValue B) {
17173 if (A.getOpcode() != ISD::INTRINSIC_WO_CHAIN)
17174 return SDValue();
17175 unsigned Opc = A.getConstantOperandVal(0);
17176 if (Opc != Intrinsic::arm_mve_vcmlaq)
17177 return SDValue();
17178 SDValue VCMLA = DAG.getNode(
17179 ISD::INTRINSIC_WO_CHAIN, DL, VT, A.getOperand(0), A.getOperand(1),
17180 DAG.getNode(ISD::FADD, DL, VT, A.getOperand(2), B, N->getFlags()),
17181 A.getOperand(3), A.getOperand(4));
17182 VCMLA->setFlags(A->getFlags());
17183 return VCMLA;
17184 };
17185 if (SDValue R = ReassocComplex(LHS, RHS))
17186 return R;
17187 if (SDValue R = ReassocComplex(RHS, LHS))
17188 return R;
17189
17190 return SDValue();
17191}
17192
17194 const ARMSubtarget *Subtarget) {
17195 if (SDValue S = PerformFAddVSelectCombine(N, DAG, Subtarget))
17196 return S;
17197 if (SDValue S = PerformFADDVCMLACombine(N, DAG))
17198 return S;
17199 return SDValue();
17200}
17201
17202/// PerformVMulVCTPCombine - VCVT (fixed-point to floating-point, Advanced SIMD)
17203/// can replace combinations of VCVT (integer to floating-point) and VMUL
17204/// when the VMUL has a constant operand that is a power of 2.
17205///
17206/// Example (assume d17 = <float 0.125, float 0.125>):
17207/// vcvt.f32.s32 d16, d16
17208/// vmul.f32 d16, d16, d17
17209/// becomes:
17210/// vcvt.f32.s32 d16, d16, #3
17212 const ARMSubtarget *Subtarget) {
17213 if (!Subtarget->hasNEON())
17214 return SDValue();
17215
17216 SDValue Op = N->getOperand(0);
17217 unsigned OpOpcode = Op.getNode()->getOpcode();
17218 if (!N->getValueType(0).isVector() || !N->getValueType(0).isSimple() ||
17219 (OpOpcode != ISD::SINT_TO_FP && OpOpcode != ISD::UINT_TO_FP))
17220 return SDValue();
17221
17222 SDValue ConstVec = N->getOperand(1);
17223 if (!isa<BuildVectorSDNode>(ConstVec))
17224 return SDValue();
17225
17226 MVT FloatTy = N->getSimpleValueType(0).getVectorElementType();
17227 uint32_t FloatBits = FloatTy.getSizeInBits();
17228 MVT IntTy = Op.getOperand(0).getSimpleValueType().getVectorElementType();
17229 uint32_t IntBits = IntTy.getSizeInBits();
17230 unsigned NumLanes = Op.getValueType().getVectorNumElements();
17231 if (FloatBits != 32 || IntBits > 32 || (NumLanes != 4 && NumLanes != 2)) {
17232 // These instructions only exist converting from i32 to f32. We can handle
17233 // smaller integers by generating an extra extend, but larger ones would
17234 // be lossy. We also can't handle anything other than 2 or 4 lanes, since
17235 // these instructions only support v2i32/v4i32 types.
17236 return SDValue();
17237 }
17238
17239 ConstantFPSDNode *CN = isConstOrConstSplatFP(ConstVec, true);
17240 APFloat Recip(0.0f);
17241 if (!CN || !CN->getValueAPF().getExactInverse(&Recip))
17242 return SDValue();
17243
17244 bool IsExact;
17245 APSInt IntVal(33);
17246 if (Recip.convertToInteger(IntVal, APFloat::rmTowardZero, &IsExact) !=
17247 APFloat::opOK ||
17248 !IsExact)
17249 return SDValue();
17250
17251 int32_t C = IntVal.exactLogBase2();
17252 if (C == -1 || C == 0 || C > 32)
17253 return SDValue();
17254
17255 SDLoc DL(N);
17256 bool isSigned = OpOpcode == ISD::SINT_TO_FP;
17257 SDValue ConvInput = Op.getOperand(0);
17258 if (IntBits < FloatBits)
17260 NumLanes == 2 ? MVT::v2i32 : MVT::v4i32, ConvInput);
17261
17262 unsigned IntrinsicOpcode = isSigned ? Intrinsic::arm_neon_vcvtfxs2fp
17263 : Intrinsic::arm_neon_vcvtfxu2fp;
17264 return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, DL, Op.getValueType(),
17265 DAG.getConstant(IntrinsicOpcode, DL, MVT::i32), ConvInput,
17266 DAG.getConstant(C, DL, MVT::i32));
17267}
17268
17270 const ARMSubtarget *ST) {
17271 if (!ST->hasMVEIntegerOps())
17272 return SDValue();
17273
17274 assert(N->getOpcode() == ISD::VECREDUCE_ADD);
17275 EVT ResVT = N->getValueType(0);
17276 SDValue N0 = N->getOperand(0);
17277 SDLoc dl(N);
17278
17279 // Try to turn vecreduce_add(add(x, y)) into vecreduce(x) + vecreduce(y)
17280 if (ResVT == MVT::i32 && N0.getOpcode() == ISD::ADD &&
17281 (N0.getValueType() == MVT::v4i32 || N0.getValueType() == MVT::v8i16 ||
17282 N0.getValueType() == MVT::v16i8)) {
17283 SDValue Red0 = DAG.getNode(ISD::VECREDUCE_ADD, dl, ResVT, N0.getOperand(0));
17284 SDValue Red1 = DAG.getNode(ISD::VECREDUCE_ADD, dl, ResVT, N0.getOperand(1));
17285 return DAG.getNode(ISD::ADD, dl, ResVT, Red0, Red1);
17286 }
17287
17288 // We are looking for something that will have illegal types if left alone,
17289 // but that we can convert to a single instruction under MVE. For example
17290 // vecreduce_add(sext(A, v8i32)) => VADDV.s16 A
17291 // or
17292 // vecreduce_add(mul(zext(A, v16i32), zext(B, v16i32))) => VMLADAV.u8 A, B
17293
17294 // The legal cases are:
17295 // VADDV u/s 8/16/32
17296 // VMLAV u/s 8/16/32
17297 // VADDLV u/s 32
17298 // VMLALV u/s 16/32
17299
17300 // If the input vector is smaller than legal (v4i8/v4i16 for example) we can
17301 // extend it and use v4i32 instead.
17302 auto ExtTypeMatches = [](SDValue A, ArrayRef<MVT> ExtTypes) {
17303 EVT AVT = A.getValueType();
17304 return any_of(ExtTypes, [&](MVT Ty) {
17305 return AVT.getVectorNumElements() == Ty.getVectorNumElements() &&
17306 AVT.bitsLE(Ty);
17307 });
17308 };
17309 auto ExtendIfNeeded = [&](SDValue A, unsigned ExtendCode) {
17310 EVT AVT = A.getValueType();
17311 if (!AVT.is128BitVector())
17312 A = DAG.getNode(
17313 ExtendCode, dl,
17315 *DAG.getContext(),
17317 A);
17318 return A;
17319 };
17320 auto IsVADDV = [&](MVT RetTy, unsigned ExtendCode, ArrayRef<MVT> ExtTypes) {
17321 if (ResVT != RetTy || N0->getOpcode() != ExtendCode)
17322 return SDValue();
17323 SDValue A = N0->getOperand(0);
17324 if (ExtTypeMatches(A, ExtTypes))
17325 return ExtendIfNeeded(A, ExtendCode);
17326 return SDValue();
17327 };
17328 auto IsPredVADDV = [&](MVT RetTy, unsigned ExtendCode,
17329 ArrayRef<MVT> ExtTypes, SDValue &Mask) {
17330 if (ResVT != RetTy || N0->getOpcode() != ISD::VSELECT ||
17332 return SDValue();
17333 Mask = N0->getOperand(0);
17334 SDValue Ext = N0->getOperand(1);
17335 if (Ext->getOpcode() != ExtendCode)
17336 return SDValue();
17337 SDValue A = Ext->getOperand(0);
17338 if (ExtTypeMatches(A, ExtTypes))
17339 return ExtendIfNeeded(A, ExtendCode);
17340 return SDValue();
17341 };
17342 auto IsVMLAV = [&](MVT RetTy, unsigned ExtendCode, ArrayRef<MVT> ExtTypes,
17343 SDValue &A, SDValue &B) {
17344 // For a vmla we are trying to match a larger pattern:
17345 // ExtA = sext/zext A
17346 // ExtB = sext/zext B
17347 // Mul = mul ExtA, ExtB
17348 // vecreduce.add Mul
17349 // There might also be en extra extend between the mul and the addreduce, so
17350 // long as the bitwidth is high enough to make them equivalent (for example
17351 // original v8i16 might be mul at v8i32 and the reduce happens at v8i64).
17352 if (ResVT != RetTy)
17353 return false;
17354 SDValue Mul = N0;
17355 if (Mul->getOpcode() == ExtendCode &&
17356 Mul->getOperand(0).getScalarValueSizeInBits() * 2 >=
17357 ResVT.getScalarSizeInBits())
17358 Mul = Mul->getOperand(0);
17359 if (Mul->getOpcode() != ISD::MUL)
17360 return false;
17361 SDValue ExtA = Mul->getOperand(0);
17362 SDValue ExtB = Mul->getOperand(1);
17363 if (ExtA->getOpcode() != ExtendCode || ExtB->getOpcode() != ExtendCode)
17364 return false;
17365 A = ExtA->getOperand(0);
17366 B = ExtB->getOperand(0);
17367 if (ExtTypeMatches(A, ExtTypes) && ExtTypeMatches(B, ExtTypes)) {
17368 A = ExtendIfNeeded(A, ExtendCode);
17369 B = ExtendIfNeeded(B, ExtendCode);
17370 return true;
17371 }
17372 return false;
17373 };
17374 auto IsPredVMLAV = [&](MVT RetTy, unsigned ExtendCode, ArrayRef<MVT> ExtTypes,
17375 SDValue &A, SDValue &B, SDValue &Mask) {
17376 // Same as the pattern above with a select for the zero predicated lanes
17377 // ExtA = sext/zext A
17378 // ExtB = sext/zext B
17379 // Mul = mul ExtA, ExtB
17380 // N0 = select Mask, Mul, 0
17381 // vecreduce.add N0
17382 if (ResVT != RetTy || N0->getOpcode() != ISD::VSELECT ||
17384 return false;
17385 Mask = N0->getOperand(0);
17386 SDValue Mul = N0->getOperand(1);
17387 if (Mul->getOpcode() == ExtendCode &&
17388 Mul->getOperand(0).getScalarValueSizeInBits() * 2 >=
17389 ResVT.getScalarSizeInBits())
17390 Mul = Mul->getOperand(0);
17391 if (Mul->getOpcode() != ISD::MUL)
17392 return false;
17393 SDValue ExtA = Mul->getOperand(0);
17394 SDValue ExtB = Mul->getOperand(1);
17395 if (ExtA->getOpcode() != ExtendCode || ExtB->getOpcode() != ExtendCode)
17396 return false;
17397 A = ExtA->getOperand(0);
17398 B = ExtB->getOperand(0);
17399 if (ExtTypeMatches(A, ExtTypes) && ExtTypeMatches(B, ExtTypes)) {
17400 A = ExtendIfNeeded(A, ExtendCode);
17401 B = ExtendIfNeeded(B, ExtendCode);
17402 return true;
17403 }
17404 return false;
17405 };
17406 auto Create64bitNode = [&](unsigned Opcode, ArrayRef<SDValue> Ops) {
17407 // Split illegal MVT::v16i8->i64 vector reductions into two legal v8i16->i64
17408 // reductions. The operands are extended with MVEEXT, but as they are
17409 // reductions the lane orders do not matter. MVEEXT may be combined with
17410 // loads to produce two extending loads, or else they will be expanded to
17411 // VREV/VMOVL.
17412 EVT VT = Ops[0].getValueType();
17413 if (VT == MVT::v16i8) {
17414 assert((Opcode == ARMISD::VMLALVs || Opcode == ARMISD::VMLALVu) &&
17415 "Unexpected illegal long reduction opcode");
17416 bool IsUnsigned = Opcode == ARMISD::VMLALVu;
17417
17418 SDValue Ext0 =
17419 DAG.getNode(IsUnsigned ? ARMISD::MVEZEXT : ARMISD::MVESEXT, dl,
17420 DAG.getVTList(MVT::v8i16, MVT::v8i16), Ops[0]);
17421 SDValue Ext1 =
17422 DAG.getNode(IsUnsigned ? ARMISD::MVEZEXT : ARMISD::MVESEXT, dl,
17423 DAG.getVTList(MVT::v8i16, MVT::v8i16), Ops[1]);
17424
17425 SDValue MLA0 = DAG.getNode(Opcode, dl, DAG.getVTList(MVT::i32, MVT::i32),
17426 Ext0, Ext1);
17427 SDValue MLA1 =
17428 DAG.getNode(IsUnsigned ? ARMISD::VMLALVAu : ARMISD::VMLALVAs, dl,
17429 DAG.getVTList(MVT::i32, MVT::i32), MLA0, MLA0.getValue(1),
17430 Ext0.getValue(1), Ext1.getValue(1));
17431 return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, MLA1, MLA1.getValue(1));
17432 }
17433 SDValue Node = DAG.getNode(Opcode, dl, {MVT::i32, MVT::i32}, Ops);
17434 return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Node,
17435 SDValue(Node.getNode(), 1));
17436 };
17437
17438 SDValue A, B;
17439 SDValue Mask;
17440 if (IsVMLAV(MVT::i32, ISD::SIGN_EXTEND, {MVT::v8i16, MVT::v16i8}, A, B))
17441 return DAG.getNode(ARMISD::VMLAVs, dl, ResVT, A, B);
17442 if (IsVMLAV(MVT::i32, ISD::ZERO_EXTEND, {MVT::v8i16, MVT::v16i8}, A, B))
17443 return DAG.getNode(ARMISD::VMLAVu, dl, ResVT, A, B);
17444 if (IsVMLAV(MVT::i64, ISD::SIGN_EXTEND, {MVT::v16i8, MVT::v8i16, MVT::v4i32},
17445 A, B))
17446 return Create64bitNode(ARMISD::VMLALVs, {A, B});
17447 if (IsVMLAV(MVT::i64, ISD::ZERO_EXTEND, {MVT::v16i8, MVT::v8i16, MVT::v4i32},
17448 A, B))
17449 return Create64bitNode(ARMISD::VMLALVu, {A, B});
17450 if (IsVMLAV(MVT::i16, ISD::SIGN_EXTEND, {MVT::v16i8}, A, B))
17451 return DAG.getNode(ISD::TRUNCATE, dl, ResVT,
17452 DAG.getNode(ARMISD::VMLAVs, dl, MVT::i32, A, B));
17453 if (IsVMLAV(MVT::i16, ISD::ZERO_EXTEND, {MVT::v16i8}, A, B))
17454 return DAG.getNode(ISD::TRUNCATE, dl, ResVT,
17455 DAG.getNode(ARMISD::VMLAVu, dl, MVT::i32, A, B));
17456
17457 if (IsPredVMLAV(MVT::i32, ISD::SIGN_EXTEND, {MVT::v8i16, MVT::v16i8}, A, B,
17458 Mask))
17459 return DAG.getNode(ARMISD::VMLAVps, dl, ResVT, A, B, Mask);
17460 if (IsPredVMLAV(MVT::i32, ISD::ZERO_EXTEND, {MVT::v8i16, MVT::v16i8}, A, B,
17461 Mask))
17462 return DAG.getNode(ARMISD::VMLAVpu, dl, ResVT, A, B, Mask);
17463 if (IsPredVMLAV(MVT::i64, ISD::SIGN_EXTEND, {MVT::v8i16, MVT::v4i32}, A, B,
17464 Mask))
17465 return Create64bitNode(ARMISD::VMLALVps, {A, B, Mask});
17466 if (IsPredVMLAV(MVT::i64, ISD::ZERO_EXTEND, {MVT::v8i16, MVT::v4i32}, A, B,
17467 Mask))
17468 return Create64bitNode(ARMISD::VMLALVpu, {A, B, Mask});
17469 if (IsPredVMLAV(MVT::i16, ISD::SIGN_EXTEND, {MVT::v16i8}, A, B, Mask))
17470 return DAG.getNode(ISD::TRUNCATE, dl, ResVT,
17471 DAG.getNode(ARMISD::VMLAVps, dl, MVT::i32, A, B, Mask));
17472 if (IsPredVMLAV(MVT::i16, ISD::ZERO_EXTEND, {MVT::v16i8}, A, B, Mask))
17473 return DAG.getNode(ISD::TRUNCATE, dl, ResVT,
17474 DAG.getNode(ARMISD::VMLAVpu, dl, MVT::i32, A, B, Mask));
17475
17476 if (SDValue A = IsVADDV(MVT::i32, ISD::SIGN_EXTEND, {MVT::v8i16, MVT::v16i8}))
17477 return DAG.getNode(ARMISD::VADDVs, dl, ResVT, A);
17478 if (SDValue A = IsVADDV(MVT::i32, ISD::ZERO_EXTEND, {MVT::v8i16, MVT::v16i8}))
17479 return DAG.getNode(ARMISD::VADDVu, dl, ResVT, A);
17480 if (SDValue A = IsVADDV(MVT::i64, ISD::SIGN_EXTEND, {MVT::v4i32}))
17481 return Create64bitNode(ARMISD::VADDLVs, {A});
17482 if (SDValue A = IsVADDV(MVT::i64, ISD::ZERO_EXTEND, {MVT::v4i32}))
17483 return Create64bitNode(ARMISD::VADDLVu, {A});
17484 if (SDValue A = IsVADDV(MVT::i16, ISD::SIGN_EXTEND, {MVT::v16i8}))
17485 return DAG.getNode(ISD::TRUNCATE, dl, ResVT,
17486 DAG.getNode(ARMISD::VADDVs, dl, MVT::i32, A));
17487 if (SDValue A = IsVADDV(MVT::i16, ISD::ZERO_EXTEND, {MVT::v16i8}))
17488 return DAG.getNode(ISD::TRUNCATE, dl, ResVT,
17489 DAG.getNode(ARMISD::VADDVu, dl, MVT::i32, A));
17490
17491 if (SDValue A = IsPredVADDV(MVT::i32, ISD::SIGN_EXTEND, {MVT::v8i16, MVT::v16i8}, Mask))
17492 return DAG.getNode(ARMISD::VADDVps, dl, ResVT, A, Mask);
17493 if (SDValue A = IsPredVADDV(MVT::i32, ISD::ZERO_EXTEND, {MVT::v8i16, MVT::v16i8}, Mask))
17494 return DAG.getNode(ARMISD::VADDVpu, dl, ResVT, A, Mask);
17495 if (SDValue A = IsPredVADDV(MVT::i64, ISD::SIGN_EXTEND, {MVT::v4i32}, Mask))
17496 return Create64bitNode(ARMISD::VADDLVps, {A, Mask});
17497 if (SDValue A = IsPredVADDV(MVT::i64, ISD::ZERO_EXTEND, {MVT::v4i32}, Mask))
17498 return Create64bitNode(ARMISD::VADDLVpu, {A, Mask});
17499 if (SDValue A = IsPredVADDV(MVT::i16, ISD::SIGN_EXTEND, {MVT::v16i8}, Mask))
17500 return DAG.getNode(ISD::TRUNCATE, dl, ResVT,
17501 DAG.getNode(ARMISD::VADDVps, dl, MVT::i32, A, Mask));
17502 if (SDValue A = IsPredVADDV(MVT::i16, ISD::ZERO_EXTEND, {MVT::v16i8}, Mask))
17503 return DAG.getNode(ISD::TRUNCATE, dl, ResVT,
17504 DAG.getNode(ARMISD::VADDVpu, dl, MVT::i32, A, Mask));
17505
17506 // Some complications. We can get a case where the two inputs of the mul are
17507 // the same, then the output sext will have been helpfully converted to a
17508 // zext. Turn it back.
17509 SDValue Op = N0;
17510 if (Op->getOpcode() == ISD::VSELECT)
17511 Op = Op->getOperand(1);
17512 if (Op->getOpcode() == ISD::ZERO_EXTEND &&
17513 Op->getOperand(0)->getOpcode() == ISD::MUL) {
17514 SDValue Mul = Op->getOperand(0);
17515 if (Mul->getOperand(0) == Mul->getOperand(1) &&
17516 Mul->getOperand(0)->getOpcode() == ISD::SIGN_EXTEND) {
17517 SDValue Ext = DAG.getNode(ISD::SIGN_EXTEND, dl, N0->getValueType(0), Mul);
17518 if (Op != N0)
17519 Ext = DAG.getNode(ISD::VSELECT, dl, N0->getValueType(0),
17520 N0->getOperand(0), Ext, N0->getOperand(2));
17521 return DAG.getNode(ISD::VECREDUCE_ADD, dl, ResVT, Ext);
17522 }
17523 }
17524
17525 return SDValue();
17526}
17527
17528// Looks for vaddv(shuffle) or vmlav(shuffle, shuffle), with a shuffle where all
17529// the lanes are used. Due to the reduction being commutative the shuffle can be
17530// removed.
17532 unsigned VecOp = N->getOperand(0).getValueType().isVector() ? 0 : 2;
17533 auto *Shuf = dyn_cast<ShuffleVectorSDNode>(N->getOperand(VecOp));
17534 if (!Shuf || !Shuf->getOperand(1).isUndef())
17535 return SDValue();
17536
17537 // Check all elements are used once in the mask.
17538 ArrayRef<int> Mask = Shuf->getMask();
17539 APInt SetElts(Mask.size(), 0);
17540 for (int E : Mask) {
17541 if (E < 0 || E >= (int)Mask.size())
17542 return SDValue();
17543 SetElts.setBit(E);
17544 }
17545 if (!SetElts.isAllOnes())
17546 return SDValue();
17547
17548 if (N->getNumOperands() != VecOp + 1) {
17549 auto *Shuf2 = dyn_cast<ShuffleVectorSDNode>(N->getOperand(VecOp + 1));
17550 if (!Shuf2 || !Shuf2->getOperand(1).isUndef() || Shuf2->getMask() != Mask)
17551 return SDValue();
17552 }
17553
17555 for (SDValue Op : N->ops()) {
17556 if (Op.getValueType().isVector())
17557 Ops.push_back(Op.getOperand(0));
17558 else
17559 Ops.push_back(Op);
17560 }
17561 return DAG.getNode(N->getOpcode(), SDLoc(N), N->getVTList(), Ops);
17562}
17563
17566 SDValue Op0 = N->getOperand(0);
17567 SDValue Op1 = N->getOperand(1);
17568 unsigned IsTop = N->getConstantOperandVal(2);
17569
17570 // VMOVNT a undef -> a
17571 // VMOVNB a undef -> a
17572 // VMOVNB undef a -> a
17573 if (Op1->isUndef())
17574 return Op0;
17575 if (Op0->isUndef() && !IsTop)
17576 return Op1;
17577
17578 // VMOVNt(c, VQMOVNb(a, b)) => VQMOVNt(c, b)
17579 // VMOVNb(c, VQMOVNb(a, b)) => VQMOVNb(c, b)
17580 if ((Op1->getOpcode() == ARMISD::VQMOVNs ||
17581 Op1->getOpcode() == ARMISD::VQMOVNu) &&
17582 Op1->getConstantOperandVal(2) == 0)
17583 return DCI.DAG.getNode(Op1->getOpcode(), SDLoc(Op1), N->getValueType(0),
17584 Op0, Op1->getOperand(1), N->getOperand(2));
17585
17586 // Only the bottom lanes from Qm (Op1) and either the top or bottom lanes from
17587 // Qd (Op0) are demanded from a VMOVN, depending on whether we are inserting
17588 // into the top or bottom lanes.
17589 unsigned NumElts = N->getValueType(0).getVectorNumElements();
17590 APInt Op1DemandedElts = APInt::getSplat(NumElts, APInt::getLowBitsSet(2, 1));
17591 APInt Op0DemandedElts =
17592 IsTop ? Op1DemandedElts
17593 : APInt::getSplat(NumElts, APInt::getHighBitsSet(2, 1));
17594
17595 const TargetLowering &TLI = DCI.DAG.getTargetLoweringInfo();
17596 if (TLI.SimplifyDemandedVectorElts(Op0, Op0DemandedElts, DCI))
17597 return SDValue(N, 0);
17598 if (TLI.SimplifyDemandedVectorElts(Op1, Op1DemandedElts, DCI))
17599 return SDValue(N, 0);
17600
17601 return SDValue();
17602}
17603
17606 SDValue Op0 = N->getOperand(0);
17607 unsigned IsTop = N->getConstantOperandVal(2);
17608
17609 unsigned NumElts = N->getValueType(0).getVectorNumElements();
17610 APInt Op0DemandedElts =
17611 APInt::getSplat(NumElts, IsTop ? APInt::getLowBitsSet(2, 1)
17612 : APInt::getHighBitsSet(2, 1));
17613
17614 const TargetLowering &TLI = DCI.DAG.getTargetLoweringInfo();
17615 if (TLI.SimplifyDemandedVectorElts(Op0, Op0DemandedElts, DCI))
17616 return SDValue(N, 0);
17617 return SDValue();
17618}
17619
17622 EVT VT = N->getValueType(0);
17623 SDValue LHS = N->getOperand(0);
17624 SDValue RHS = N->getOperand(1);
17625
17626 auto *Shuf0 = dyn_cast<ShuffleVectorSDNode>(LHS);
17627 auto *Shuf1 = dyn_cast<ShuffleVectorSDNode>(RHS);
17628 // Turn VQDMULH(shuffle, shuffle) -> shuffle(VQDMULH)
17629 if (Shuf0 && Shuf1 && Shuf0->getMask().equals(Shuf1->getMask()) &&
17630 LHS.getOperand(1).isUndef() && RHS.getOperand(1).isUndef() &&
17631 (LHS.hasOneUse() || RHS.hasOneUse() || LHS == RHS)) {
17632 SDLoc DL(N);
17633 SDValue NewBinOp = DCI.DAG.getNode(N->getOpcode(), DL, VT,
17634 LHS.getOperand(0), RHS.getOperand(0));
17635 SDValue UndefV = LHS.getOperand(1);
17636 return DCI.DAG.getVectorShuffle(VT, DL, NewBinOp, UndefV, Shuf0->getMask());
17637 }
17638 return SDValue();
17639}
17640
17642 SDLoc DL(N);
17643 SDValue Op0 = N->getOperand(0);
17644 SDValue Op1 = N->getOperand(1);
17645
17646 // Turn X << -C -> X >> C and viceversa. The negative shifts can come up from
17647 // uses of the intrinsics.
17648 if (auto C = dyn_cast<ConstantSDNode>(N->getOperand(2))) {
17649 int ShiftAmt = C->getSExtValue();
17650 if (ShiftAmt == 0) {
17651 SDValue Merge = DAG.getMergeValues({Op0, Op1}, DL);
17652 DAG.ReplaceAllUsesWith(N, Merge.getNode());
17653 return SDValue();
17654 }
17655
17656 if (ShiftAmt >= -32 && ShiftAmt < 0) {
17657 unsigned NewOpcode =
17658 N->getOpcode() == ARMISD::LSLL ? ARMISD::LSRL : ARMISD::LSLL;
17659 SDValue NewShift = DAG.getNode(NewOpcode, DL, N->getVTList(), Op0, Op1,
17660 DAG.getConstant(-ShiftAmt, DL, MVT::i32));
17661 DAG.ReplaceAllUsesWith(N, NewShift.getNode());
17662 return NewShift;
17663 }
17664 }
17665
17666 return SDValue();
17667}
17668
17669/// PerformIntrinsicCombine - ARM-specific DAG combining for intrinsics.
17671 DAGCombinerInfo &DCI) const {
17672 SelectionDAG &DAG = DCI.DAG;
17673 unsigned IntNo = N->getConstantOperandVal(0);
17674 switch (IntNo) {
17675 default:
17676 // Don't do anything for most intrinsics.
17677 break;
17678
17679 // Vector shifts: check for immediate versions and lower them.
17680 // Note: This is done during DAG combining instead of DAG legalizing because
17681 // the build_vectors for 64-bit vector element shift counts are generally
17682 // not legal, and it is hard to see their values after they get legalized to
17683 // loads from a constant pool.
17684 case Intrinsic::arm_neon_vshifts:
17685 case Intrinsic::arm_neon_vshiftu:
17686 case Intrinsic::arm_neon_vrshifts:
17687 case Intrinsic::arm_neon_vrshiftu:
17688 case Intrinsic::arm_neon_vrshiftn:
17689 case Intrinsic::arm_neon_vqshifts:
17690 case Intrinsic::arm_neon_vqshiftu:
17691 case Intrinsic::arm_neon_vqshiftsu:
17692 case Intrinsic::arm_neon_vqshiftns:
17693 case Intrinsic::arm_neon_vqshiftnu:
17694 case Intrinsic::arm_neon_vqshiftnsu:
17695 case Intrinsic::arm_neon_vqrshiftns:
17696 case Intrinsic::arm_neon_vqrshiftnu:
17697 case Intrinsic::arm_neon_vqrshiftnsu: {
17698 EVT VT = N->getOperand(1).getValueType();
17699 int64_t Cnt;
17700 unsigned VShiftOpc = 0;
17701
17702 switch (IntNo) {
17703 case Intrinsic::arm_neon_vshifts:
17704 case Intrinsic::arm_neon_vshiftu:
17705 if (isVShiftLImm(N->getOperand(2), VT, false, Cnt)) {
17706 VShiftOpc = ARMISD::VSHLIMM;
17707 break;
17708 }
17709 if (isVShiftRImm(N->getOperand(2), VT, false, true, Cnt)) {
17710 VShiftOpc = (IntNo == Intrinsic::arm_neon_vshifts ? ARMISD::VSHRsIMM
17711 : ARMISD::VSHRuIMM);
17712 break;
17713 }
17714 return SDValue();
17715
17716 case Intrinsic::arm_neon_vrshifts:
17717 case Intrinsic::arm_neon_vrshiftu:
17718 if (isVShiftRImm(N->getOperand(2), VT, false, true, Cnt))
17719 break;
17720 return SDValue();
17721
17722 case Intrinsic::arm_neon_vqshifts:
17723 case Intrinsic::arm_neon_vqshiftu:
17724 if (isVShiftLImm(N->getOperand(2), VT, false, Cnt))
17725 break;
17726 return SDValue();
17727
17728 case Intrinsic::arm_neon_vqshiftsu:
17729 if (isVShiftLImm(N->getOperand(2), VT, false, Cnt))
17730 break;
17731 llvm_unreachable("invalid shift count for vqshlu intrinsic");
17732
17733 case Intrinsic::arm_neon_vrshiftn:
17734 case Intrinsic::arm_neon_vqshiftns:
17735 case Intrinsic::arm_neon_vqshiftnu:
17736 case Intrinsic::arm_neon_vqshiftnsu:
17737 case Intrinsic::arm_neon_vqrshiftns:
17738 case Intrinsic::arm_neon_vqrshiftnu:
17739 case Intrinsic::arm_neon_vqrshiftnsu:
17740 // Narrowing shifts require an immediate right shift.
17741 if (isVShiftRImm(N->getOperand(2), VT, true, true, Cnt))
17742 break;
17743 llvm_unreachable("invalid shift count for narrowing vector shift "
17744 "intrinsic");
17745
17746 default:
17747 llvm_unreachable("unhandled vector shift");
17748 }
17749
17750 switch (IntNo) {
17751 case Intrinsic::arm_neon_vshifts:
17752 case Intrinsic::arm_neon_vshiftu:
17753 // Opcode already set above.
17754 break;
17755 case Intrinsic::arm_neon_vrshifts:
17756 VShiftOpc = ARMISD::VRSHRsIMM;
17757 break;
17758 case Intrinsic::arm_neon_vrshiftu:
17759 VShiftOpc = ARMISD::VRSHRuIMM;
17760 break;
17761 case Intrinsic::arm_neon_vrshiftn:
17762 VShiftOpc = ARMISD::VRSHRNIMM;
17763 break;
17764 case Intrinsic::arm_neon_vqshifts:
17765 VShiftOpc = ARMISD::VQSHLsIMM;
17766 break;
17767 case Intrinsic::arm_neon_vqshiftu:
17768 VShiftOpc = ARMISD::VQSHLuIMM;
17769 break;
17770 case Intrinsic::arm_neon_vqshiftsu:
17771 VShiftOpc = ARMISD::VQSHLsuIMM;
17772 break;
17773 case Intrinsic::arm_neon_vqshiftns:
17774 VShiftOpc = ARMISD::VQSHRNsIMM;
17775 break;
17776 case Intrinsic::arm_neon_vqshiftnu:
17777 VShiftOpc = ARMISD::VQSHRNuIMM;
17778 break;
17779 case Intrinsic::arm_neon_vqshiftnsu:
17780 VShiftOpc = ARMISD::VQSHRNsuIMM;
17781 break;
17782 case Intrinsic::arm_neon_vqrshiftns:
17783 VShiftOpc = ARMISD::VQRSHRNsIMM;
17784 break;
17785 case Intrinsic::arm_neon_vqrshiftnu:
17786 VShiftOpc = ARMISD::VQRSHRNuIMM;
17787 break;
17788 case Intrinsic::arm_neon_vqrshiftnsu:
17789 VShiftOpc = ARMISD::VQRSHRNsuIMM;
17790 break;
17791 }
17792
17793 SDLoc dl(N);
17794 return DAG.getNode(VShiftOpc, dl, N->getValueType(0),
17795 N->getOperand(1), DAG.getConstant(Cnt, dl, MVT::i32));
17796 }
17797
17798 case Intrinsic::arm_neon_vshiftins: {
17799 EVT VT = N->getOperand(1).getValueType();
17800 int64_t Cnt;
17801 unsigned VShiftOpc = 0;
17802
17803 if (isVShiftLImm(N->getOperand(3), VT, false, Cnt))
17804 VShiftOpc = ARMISD::VSLIIMM;
17805 else if (isVShiftRImm(N->getOperand(3), VT, false, true, Cnt))
17806 VShiftOpc = ARMISD::VSRIIMM;
17807 else {
17808 llvm_unreachable("invalid shift count for vsli/vsri intrinsic");
17809 }
17810
17811 SDLoc dl(N);
17812 return DAG.getNode(VShiftOpc, dl, N->getValueType(0),
17813 N->getOperand(1), N->getOperand(2),
17814 DAG.getConstant(Cnt, dl, MVT::i32));
17815 }
17816
17817 case Intrinsic::arm_neon_vqrshifts:
17818 case Intrinsic::arm_neon_vqrshiftu:
17819 // No immediate versions of these to check for.
17820 break;
17821
17822 case Intrinsic::arm_neon_vbsl: {
17823 SDLoc dl(N);
17824 return DAG.getNode(ARMISD::VBSP, dl, N->getValueType(0), N->getOperand(1),
17825 N->getOperand(2), N->getOperand(3));
17826 }
17827 case Intrinsic::arm_mve_vqdmlah:
17828 case Intrinsic::arm_mve_vqdmlash:
17829 case Intrinsic::arm_mve_vqrdmlah:
17830 case Intrinsic::arm_mve_vqrdmlash:
17831 case Intrinsic::arm_mve_vmla_n_predicated:
17832 case Intrinsic::arm_mve_vmlas_n_predicated:
17833 case Intrinsic::arm_mve_vqdmlah_predicated:
17834 case Intrinsic::arm_mve_vqdmlash_predicated:
17835 case Intrinsic::arm_mve_vqrdmlah_predicated:
17836 case Intrinsic::arm_mve_vqrdmlash_predicated: {
17837 // These intrinsics all take an i32 scalar operand which is narrowed to the
17838 // size of a single lane of the vector type they return. So we don't need
17839 // any bits of that operand above that point, which allows us to eliminate
17840 // uxth/sxth.
17841 unsigned BitWidth = N->getValueType(0).getScalarSizeInBits();
17842 APInt DemandedMask = APInt::getLowBitsSet(32, BitWidth);
17843 if (SimplifyDemandedBits(N->getOperand(3), DemandedMask, DCI))
17844 return SDValue();
17845 break;
17846 }
17847
17848 case Intrinsic::arm_mve_minv:
17849 case Intrinsic::arm_mve_maxv:
17850 case Intrinsic::arm_mve_minav:
17851 case Intrinsic::arm_mve_maxav:
17852 case Intrinsic::arm_mve_minv_predicated:
17853 case Intrinsic::arm_mve_maxv_predicated:
17854 case Intrinsic::arm_mve_minav_predicated:
17855 case Intrinsic::arm_mve_maxav_predicated: {
17856 // These intrinsics all take an i32 scalar operand which is narrowed to the
17857 // size of a single lane of the vector type they take as the other input.
17858 unsigned BitWidth = N->getOperand(2)->getValueType(0).getScalarSizeInBits();
17859 APInt DemandedMask = APInt::getLowBitsSet(32, BitWidth);
17860 if (SimplifyDemandedBits(N->getOperand(1), DemandedMask, DCI))
17861 return SDValue();
17862 break;
17863 }
17864
17865 case Intrinsic::arm_mve_addv: {
17866 // Turn this intrinsic straight into the appropriate ARMISD::VADDV node,
17867 // which allow PerformADDVecReduce to turn it into VADDLV when possible.
17868 bool Unsigned = N->getConstantOperandVal(2);
17869 unsigned Opc = Unsigned ? ARMISD::VADDVu : ARMISD::VADDVs;
17870 return DAG.getNode(Opc, SDLoc(N), N->getVTList(), N->getOperand(1));
17871 }
17872
17873 case Intrinsic::arm_mve_addlv:
17874 case Intrinsic::arm_mve_addlv_predicated: {
17875 // Same for these, but ARMISD::VADDLV has to be followed by a BUILD_PAIR
17876 // which recombines the two outputs into an i64
17877 bool Unsigned = N->getConstantOperandVal(2);
17878 unsigned Opc = IntNo == Intrinsic::arm_mve_addlv ?
17879 (Unsigned ? ARMISD::VADDLVu : ARMISD::VADDLVs) :
17880 (Unsigned ? ARMISD::VADDLVpu : ARMISD::VADDLVps);
17881
17883 for (unsigned i = 1, e = N->getNumOperands(); i < e; i++)
17884 if (i != 2) // skip the unsigned flag
17885 Ops.push_back(N->getOperand(i));
17886
17887 SDLoc dl(N);
17888 SDValue val = DAG.getNode(Opc, dl, {MVT::i32, MVT::i32}, Ops);
17889 return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, val.getValue(0),
17890 val.getValue(1));
17891 }
17892 }
17893
17894 return SDValue();
17895}
17896
17898 EVT VT = Y.getValueType();
17899 if (!VT.isVector())
17900 return hasAndNotCompare(Y);
17901 if (Subtarget->hasMVEIntegerOps())
17902 return VT.is128BitVector();
17903 if (Subtarget->hasNEON())
17904 return VT.is64BitVector() || VT.is128BitVector();
17905 return false;
17906}
17907
17908/// PerformShiftCombine - Checks for immediate versions of vector shifts and
17909/// lowers them. As with the vector shift intrinsics, this is done during DAG
17910/// combining instead of DAG legalizing because the build_vectors for 64-bit
17911/// vector element shift counts are generally not legal, and it is hard to see
17912/// their values after they get legalized to loads from a constant pool.
17915 const ARMSubtarget *ST) {
17916 SelectionDAG &DAG = DCI.DAG;
17917 EVT VT = N->getValueType(0);
17918
17919 if (ST->isThumb1Only() && N->getOpcode() == ISD::SHL && VT == MVT::i32 &&
17920 N->getOperand(0)->getOpcode() == ISD::AND &&
17921 N->getOperand(0)->hasOneUse()) {
17922 if (DCI.isBeforeLegalize() || DCI.isCalledByLegalizer())
17923 return SDValue();
17924 // Look for the pattern (shl (and x, AndMask), ShiftAmt). This doesn't
17925 // usually show up because instcombine prefers to canonicalize it to
17926 // (and (shl x, ShiftAmt) (shl AndMask, ShiftAmt)), but the shift can come
17927 // out of GEP lowering in some cases.
17928 SDValue N0 = N->getOperand(0);
17929 ConstantSDNode *ShiftAmtNode = dyn_cast<ConstantSDNode>(N->getOperand(1));
17930 if (!ShiftAmtNode)
17931 return SDValue();
17932 uint32_t ShiftAmt = static_cast<uint32_t>(ShiftAmtNode->getZExtValue());
17933 ConstantSDNode *AndMaskNode = dyn_cast<ConstantSDNode>(N0->getOperand(1));
17934 if (!AndMaskNode)
17935 return SDValue();
17936 uint32_t AndMask = static_cast<uint32_t>(AndMaskNode->getZExtValue());
17937 // Don't transform uxtb/uxth.
17938 if (AndMask == 255 || AndMask == 65535)
17939 return SDValue();
17940 if (isMask_32(AndMask)) {
17941 uint32_t MaskedBits = llvm::countl_zero(AndMask);
17942 if (MaskedBits > ShiftAmt) {
17943 SDLoc DL(N);
17944 SDValue SHL = DAG.getNode(ISD::SHL, DL, MVT::i32, N0->getOperand(0),
17945 DAG.getConstant(MaskedBits, DL, MVT::i32));
17946 return DAG.getNode(
17947 ISD::SRL, DL, MVT::i32, SHL,
17948 DAG.getConstant(MaskedBits - ShiftAmt, DL, MVT::i32));
17949 }
17950 }
17951 }
17952
17953 // Nothing to be done for scalar shifts.
17954 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
17955 if (!VT.isVector() || !TLI.isTypeLegal(VT))
17956 return SDValue();
17957 if (ST->hasMVEIntegerOps())
17958 return SDValue();
17959
17960 int64_t Cnt;
17961
17962 switch (N->getOpcode()) {
17963 default: llvm_unreachable("unexpected shift opcode");
17964
17965 case ISD::SHL:
17966 if (isVShiftLImm(N->getOperand(1), VT, false, Cnt)) {
17967 SDLoc dl(N);
17968 return DAG.getNode(ARMISD::VSHLIMM, dl, VT, N->getOperand(0),
17969 DAG.getConstant(Cnt, dl, MVT::i32));
17970 }
17971 break;
17972
17973 case ISD::SRA:
17974 case ISD::SRL:
17975 if (isVShiftRImm(N->getOperand(1), VT, false, false, Cnt)) {
17976 unsigned VShiftOpc =
17977 (N->getOpcode() == ISD::SRA ? ARMISD::VSHRsIMM : ARMISD::VSHRuIMM);
17978 SDLoc dl(N);
17979 return DAG.getNode(VShiftOpc, dl, VT, N->getOperand(0),
17980 DAG.getConstant(Cnt, dl, MVT::i32));
17981 }
17982 }
17983 return SDValue();
17984}
17985
17986// Look for a sign/zero/fpextend extend of a larger than legal load. This can be
17987// split into multiple extending loads, which are simpler to deal with than an
17988// arbitrary extend. For fp extends we use an integer extending load and a VCVTL
17989// to convert the type to an f32.
17991 SDValue N0 = N->getOperand(0);
17992 if (N0.getOpcode() != ISD::LOAD)
17993 return SDValue();
17995 if (!LD->isSimple() || !N0.hasOneUse() || LD->isIndexed() ||
17996 LD->getExtensionType() != ISD::NON_EXTLOAD)
17997 return SDValue();
17998 EVT FromVT = LD->getValueType(0);
17999 EVT ToVT = N->getValueType(0);
18000 if (!ToVT.isVector())
18001 return SDValue();
18003 EVT ToEltVT = ToVT.getVectorElementType();
18004 EVT FromEltVT = FromVT.getVectorElementType();
18005
18006 unsigned NumElements = 0;
18007 if (ToEltVT == MVT::i32 && FromEltVT == MVT::i8)
18008 NumElements = 4;
18009 if (ToEltVT == MVT::f32 && FromEltVT == MVT::f16)
18010 NumElements = 4;
18011 if (NumElements == 0 ||
18012 (FromEltVT != MVT::f16 && FromVT.getVectorNumElements() == NumElements) ||
18013 FromVT.getVectorNumElements() % NumElements != 0 ||
18014 !isPowerOf2_32(NumElements))
18015 return SDValue();
18016
18017 LLVMContext &C = *DAG.getContext();
18018 SDLoc DL(LD);
18019 // Details about the old load
18020 SDValue Ch = LD->getChain();
18021 SDValue BasePtr = LD->getBasePtr();
18022 Align Alignment = LD->getBaseAlign();
18023 MachineMemOperand::Flags MMOFlags = LD->getMemOperand()->getFlags();
18024 AAMDNodes AAInfo = LD->getAAInfo();
18025
18026 ISD::LoadExtType NewExtType =
18027 N->getOpcode() == ISD::SIGN_EXTEND ? ISD::SEXTLOAD : ISD::ZEXTLOAD;
18028 SDValue Offset = DAG.getPOISON(BasePtr.getValueType());
18029 EVT NewFromVT = EVT::getVectorVT(
18030 C, EVT::getIntegerVT(C, FromEltVT.getScalarSizeInBits()), NumElements);
18031 EVT NewToVT = EVT::getVectorVT(
18032 C, EVT::getIntegerVT(C, ToEltVT.getScalarSizeInBits()), NumElements);
18033
18036 for (unsigned i = 0; i < FromVT.getVectorNumElements() / NumElements; i++) {
18037 unsigned NewOffset = (i * NewFromVT.getSizeInBits()) / 8;
18038 SDValue NewPtr =
18039 DAG.getObjectPtrOffset(DL, BasePtr, TypeSize::getFixed(NewOffset));
18040
18041 SDValue NewLoad =
18042 DAG.getLoad(ISD::UNINDEXED, NewExtType, NewToVT, DL, Ch, NewPtr, Offset,
18043 LD->getPointerInfo().getWithOffset(NewOffset), NewFromVT,
18044 Alignment, MMOFlags, AAInfo);
18045 Loads.push_back(NewLoad);
18046 Chains.push_back(SDValue(NewLoad.getNode(), 1));
18047 }
18048
18049 // Float truncs need to extended with VCVTB's into their floating point types.
18050 if (FromEltVT == MVT::f16) {
18052
18053 for (unsigned i = 0; i < Loads.size(); i++) {
18054 SDValue LoadBC =
18055 DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, MVT::v8f16, Loads[i]);
18056 SDValue FPExt = DAG.getNode(ARMISD::VCVTL, DL, MVT::v4f32, LoadBC,
18057 DAG.getConstant(0, DL, MVT::i32));
18058 Extends.push_back(FPExt);
18059 }
18060
18061 Loads = Extends;
18062 }
18063
18064 SDValue NewChain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Chains);
18065 DAG.ReplaceAllUsesOfValueWith(SDValue(LD, 1), NewChain);
18066 return DAG.getNode(ISD::CONCAT_VECTORS, DL, ToVT, Loads);
18067}
18068
18069/// PerformExtendCombine - Target-specific DAG combining for ISD::SIGN_EXTEND,
18070/// ISD::ZERO_EXTEND, and ISD::ANY_EXTEND.
18072 const ARMSubtarget *ST) {
18073 SDValue N0 = N->getOperand(0);
18074 EVT VT = N->getValueType(0);
18075 SDLoc DL(N);
18076
18077 // Check for sign- and zero-extensions of vector extract operations of 8- and
18078 // 16-bit vector elements. NEON and MVE support these directly. They are
18079 // handled during DAG combining because type legalization will promote them
18080 // to 32-bit types and it is messy to recognize the operations after that.
18081 if ((ST->hasNEON() || ST->hasMVEIntegerOps()) &&
18083 SDValue Vec = N0.getOperand(0);
18084 SDValue Lane = N0.getOperand(1);
18085 EVT EltVT = N0.getValueType();
18086 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
18087
18088 if (VT == MVT::i32 &&
18089 (EltVT == MVT::i8 || EltVT == MVT::i16) &&
18090 TLI.isTypeLegal(Vec.getValueType()) &&
18091 isa<ConstantSDNode>(Lane)) {
18092
18093 unsigned Opc = 0;
18094 switch (N->getOpcode()) {
18095 default: llvm_unreachable("unexpected opcode");
18096 case ISD::SIGN_EXTEND:
18097 Opc = ARMISD::VGETLANEs;
18098 break;
18099 case ISD::ZERO_EXTEND:
18100 case ISD::ANY_EXTEND:
18101 Opc = ARMISD::VGETLANEu;
18102 break;
18103 }
18104 return DAG.getNode(Opc, DL, VT, Vec, Lane);
18105 }
18106 }
18107
18108 if (ST->hasMVEIntegerOps())
18109 if (SDValue NewLoad = PerformSplittingToWideningLoad(N, DAG))
18110 return NewLoad;
18111
18112 // Combine sext(buildvector(..)) to buildvector(sext(..)) to help avoid
18113 // difficult to lower i1 buildvector.
18114 if (ST->hasMVEIntegerOps() && N0.getValueType().getScalarSizeInBits() == 1 &&
18115 N0.getOpcode() == ISD::BUILD_VECTOR && VT.getScalarSizeInBits() <= 32) {
18117 for (unsigned I = 0; I < N0.getNumOperands(); I++) {
18118 SDValue InReg = N0.getOperand(I);
18119 if (N->getOpcode() == ISD::ZERO_EXTEND)
18120 InReg = DAG.getNode(ISD::AND, DL, InReg.getValueType(), InReg,
18121 DAG.getConstant(1, DL, InReg.getValueType()));
18122 else if (N->getOpcode() == ISD::SIGN_EXTEND)
18123 InReg = DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, InReg.getValueType(),
18124 InReg, DAG.getValueType(MVT::i1));
18125 SDValue Ext = DAG.getNode(N->getOpcode(), DL, MVT::i32, InReg);
18126 Ops.push_back(Ext);
18127 }
18128 return DAG.getNode(ISD::BUILD_VECTOR, DL, VT, Ops);
18129 }
18130
18131 return SDValue();
18132}
18133
18135 const ARMSubtarget *ST) {
18136 if (ST->hasMVEFloatOps())
18137 if (SDValue NewLoad = PerformSplittingToWideningLoad(N, DAG))
18138 return NewLoad;
18139
18140 return SDValue();
18141}
18142
18143// Lower smin(smax(x, C1), C2) to ssat or usat, if they have saturating
18144// constant bounds.
18146 const ARMSubtarget *Subtarget) {
18147 if ((Subtarget->isThumb() || !Subtarget->hasV6Ops()) &&
18148 !Subtarget->isThumb2())
18149 return SDValue();
18150
18151 EVT VT = Op.getValueType();
18152 SDValue Op0 = Op.getOperand(0);
18153
18154 if (VT != MVT::i32 ||
18155 (Op0.getOpcode() != ISD::SMIN && Op0.getOpcode() != ISD::SMAX) ||
18156 !isa<ConstantSDNode>(Op.getOperand(1)) ||
18158 return SDValue();
18159
18160 SDValue Min = Op;
18161 SDValue Max = Op0;
18162 SDValue Input = Op0.getOperand(0);
18163 if (Min.getOpcode() == ISD::SMAX)
18164 std::swap(Min, Max);
18165
18166 if (Min.getOpcode() != ISD::SMIN || Max.getOpcode() != ISD::SMAX)
18167 return SDValue();
18168
18169 APInt MinC = Min.getConstantOperandAPInt(1);
18170 APInt MaxC = Max.getConstantOperandAPInt(1);
18171 if (MaxC.sgt(MinC))
18172 return SDValue();
18173
18174 SDLoc DL(Op);
18175
18176 // A clamp whose bounds are already a saturation range maps to a single
18177 // SSAT / USAT.
18178 if ((MinC + 1).isPowerOf2()) {
18179 if (MinC == ~MaxC)
18180 return DAG.getNode(ARMISD::SSAT, DL, VT, Input,
18181 DAG.getConstant(MinC.countr_one(), DL, VT));
18182 if (MaxC == 0)
18183 return DAG.getNode(ARMISD::USAT, DL, VT, Input,
18184 DAG.getConstant(MinC.countr_one(), DL, VT));
18185 }
18186
18187 // For power-of-two clamp widths, convert the range to be zero-centered,
18188 // apply SSAT, and convert the result back.
18189 //
18190 // Width = Hi - Lo + 1
18191 // Center = Lo + Width / 2
18192 // Result = ssat(X - Center) + Center
18193 //
18194 // The idea is to shift the input so that the clamp range is centered
18195 // around zero, apply ssat, and then shift the result back.
18196 //
18197 // For example clamp(X, -118, 137) -> Width = 256, Center = 10, so it becomes
18198 // ssat(X - 10, 8) + 10
18199
18200 APInt Width = MinC - MaxC + 1;
18201 if (!Width.isPowerOf2() || Width.isOne())
18202 return SDValue();
18203 unsigned SatBit = Width.logBase2() - 1; // ssat to SatBit + 1 signed bits
18204 APInt Center = MaxC + Width.lshr(1);
18205
18206 // The rewrite is only valid when X - Center does not overflow;
18207 SDValue NegC = DAG.getConstant(-Center, DL, VT);
18209 return SDValue();
18210
18211 SDValue Shifted = DAG.getNode(ISD::ADD, DL, VT, Input, NegC);
18212 SDValue Sat = DAG.getNode(ARMISD::SSAT, DL, VT, Shifted,
18213 DAG.getConstant(SatBit, DL, VT));
18214 return DAG.getNode(ISD::ADD, DL, VT, Sat, DAG.getConstant(Center, DL, VT));
18215}
18216
18217/// PerformMinMaxCombine - Target-specific DAG combining for creating truncating
18218/// saturates.
18220 const ARMSubtarget *ST) {
18221 EVT VT = N->getValueType(0);
18222 SDValue N0 = N->getOperand(0);
18223
18224 if (VT == MVT::i32)
18225 return PerformMinMaxToSatCombine(SDValue(N, 0), DAG, ST);
18226
18227 if (!ST->hasMVEIntegerOps())
18228 return SDValue();
18229
18230 if (SDValue V = PerformVQDMULHCombine(N, DAG))
18231 return V;
18232
18233 if (VT != MVT::v4i32 && VT != MVT::v8i16)
18234 return SDValue();
18235
18236 auto IsSignedSaturate = [&](SDNode *Min, SDNode *Max) {
18237 // Check one is a smin and the other is a smax
18238 if (Min->getOpcode() != ISD::SMIN)
18239 std::swap(Min, Max);
18240 if (Min->getOpcode() != ISD::SMIN || Max->getOpcode() != ISD::SMAX)
18241 return false;
18242
18243 APInt SaturateC;
18244 if (VT == MVT::v4i32)
18245 SaturateC = APInt(32, (1 << 15) - 1, true);
18246 else //if (VT == MVT::v8i16)
18247 SaturateC = APInt(16, (1 << 7) - 1, true);
18248
18249 APInt MinC, MaxC;
18250 if (!ISD::isConstantSplatVector(Min->getOperand(1).getNode(), MinC) ||
18251 MinC != SaturateC)
18252 return false;
18253 if (!ISD::isConstantSplatVector(Max->getOperand(1).getNode(), MaxC) ||
18254 MaxC != ~SaturateC)
18255 return false;
18256 return true;
18257 };
18258
18259 if (IsSignedSaturate(N, N0.getNode())) {
18260 SDLoc DL(N);
18261 MVT ExtVT, HalfVT;
18262 if (VT == MVT::v4i32) {
18263 HalfVT = MVT::v8i16;
18264 ExtVT = MVT::v4i16;
18265 } else { // if (VT == MVT::v8i16)
18266 HalfVT = MVT::v16i8;
18267 ExtVT = MVT::v8i8;
18268 }
18269
18270 // Create a VQMOVNB with undef top lanes, then signed extended into the top
18271 // half. That extend will hopefully be removed if only the bottom bits are
18272 // demanded (though a truncating store, for example).
18273 SDValue VQMOVN =
18274 DAG.getNode(ARMISD::VQMOVNs, DL, HalfVT, DAG.getUNDEF(HalfVT),
18275 N0->getOperand(0), DAG.getConstant(0, DL, MVT::i32));
18276 SDValue Bitcast = DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, VT, VQMOVN);
18277 return DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, VT, Bitcast,
18278 DAG.getValueType(ExtVT));
18279 }
18280
18281 auto IsUnsignedSaturate = [&](SDNode *Min) {
18282 // For unsigned, we just need to check for <= 0xffff
18283 if (Min->getOpcode() != ISD::UMIN)
18284 return false;
18285
18286 APInt SaturateC;
18287 if (VT == MVT::v4i32)
18288 SaturateC = APInt(32, (1 << 16) - 1, true);
18289 else //if (VT == MVT::v8i16)
18290 SaturateC = APInt(16, (1 << 8) - 1, true);
18291
18292 APInt MinC;
18293 if (!ISD::isConstantSplatVector(Min->getOperand(1).getNode(), MinC) ||
18294 MinC != SaturateC)
18295 return false;
18296 return true;
18297 };
18298
18299 if (IsUnsignedSaturate(N)) {
18300 SDLoc DL(N);
18301 MVT HalfVT;
18302 unsigned ExtConst;
18303 if (VT == MVT::v4i32) {
18304 HalfVT = MVT::v8i16;
18305 ExtConst = 0x0000FFFF;
18306 } else { //if (VT == MVT::v8i16)
18307 HalfVT = MVT::v16i8;
18308 ExtConst = 0x00FF;
18309 }
18310
18311 // Create a VQMOVNB with undef top lanes, then ZExt into the top half with
18312 // an AND. That extend will hopefully be removed if only the bottom bits are
18313 // demanded (though a truncating store, for example).
18314 SDValue VQMOVN =
18315 DAG.getNode(ARMISD::VQMOVNu, DL, HalfVT, DAG.getUNDEF(HalfVT), N0,
18316 DAG.getConstant(0, DL, MVT::i32));
18317 SDValue Bitcast = DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, VT, VQMOVN);
18318 return DAG.getNode(ISD::AND, DL, VT, Bitcast,
18319 DAG.getConstant(ExtConst, DL, VT));
18320 }
18321
18322 return SDValue();
18323}
18324
18327 if (!C)
18328 return nullptr;
18329 const APInt *CV = &C->getAPIntValue();
18330 return CV->isPowerOf2() ? CV : nullptr;
18331}
18332
18334 // If we have a CMOV, OR and AND combination such as:
18335 // if (x & CN)
18336 // y |= CM;
18337 //
18338 // And:
18339 // * CN is a single bit;
18340 // * All bits covered by CM are known zero in y
18341 //
18342 // Then we can convert this into a sequence of BFI instructions. This will
18343 // always be a win if CM is a single bit, will always be no worse than the
18344 // TST&OR sequence if CM is two bits, and for thumb will be no worse if CM is
18345 // three bits (due to the extra IT instruction).
18346
18347 SDValue Op0 = CMOV->getOperand(0);
18348 SDValue Op1 = CMOV->getOperand(1);
18349 auto CC = CMOV->getConstantOperandAPInt(2).getLimitedValue();
18350 SDValue CmpZ = CMOV->getOperand(3);
18351
18352 // The compare must be against zero.
18353 if (!isNullConstant(CmpZ->getOperand(1)))
18354 return SDValue();
18355
18356 assert(CmpZ->getOpcode() == ARMISD::CMPZ);
18357 SDValue And = CmpZ->getOperand(0);
18358 if (And->getOpcode() != ISD::AND)
18359 return SDValue();
18360 const APInt *AndC = isPowerOf2Constant(And->getOperand(1));
18361 if (!AndC)
18362 return SDValue();
18363 SDValue X = And->getOperand(0);
18364
18365 if (CC == ARMCC::EQ) {
18366 // We're performing an "equal to zero" compare. Swap the operands so we
18367 // canonicalize on a "not equal to zero" compare.
18368 std::swap(Op0, Op1);
18369 } else {
18370 assert(CC == ARMCC::NE && "How can a CMPZ node not be EQ or NE?");
18371 }
18372
18373 if (Op1->getOpcode() != ISD::OR)
18374 return SDValue();
18375
18377 if (!OrC)
18378 return SDValue();
18379 SDValue Y = Op1->getOperand(0);
18380
18381 if (Op0 != Y)
18382 return SDValue();
18383
18384 // Now, is it profitable to continue?
18385 APInt OrCI = OrC->getAPIntValue();
18386 unsigned Heuristic = Subtarget->isThumb() ? 3 : 2;
18387 if (OrCI.popcount() > Heuristic)
18388 return SDValue();
18389
18390 // Lastly, can we determine that the bits defined by OrCI
18391 // are zero in Y?
18393 if ((OrCI & Known.Zero) != OrCI)
18394 return SDValue();
18395
18396 // OK, we can do the combine.
18397 SDValue V = Y;
18398 SDLoc dl(X);
18399 EVT VT = X.getValueType();
18400 unsigned BitInX = AndC->logBase2();
18401
18402 if (BitInX != 0) {
18403 // We must shift X first.
18404 X = DAG.getNode(ISD::SRL, dl, VT, X,
18405 DAG.getConstant(BitInX, dl, VT));
18406 }
18407
18408 for (unsigned BitInY = 0, NumActiveBits = OrCI.getActiveBits();
18409 BitInY < NumActiveBits; ++BitInY) {
18410 if (OrCI[BitInY] == 0)
18411 continue;
18412 APInt Mask(VT.getSizeInBits(), 0);
18413 Mask.setBit(BitInY);
18414 V = DAG.getNode(ARMISD::BFI, dl, VT, V, X,
18415 // Confusingly, the operand is an *inverted* mask.
18416 DAG.getConstant(~Mask, dl, VT));
18417 }
18418
18419 return V;
18420}
18421
18422// Given N, the value controlling the conditional branch, search for the loop
18423// intrinsic, returning it, along with how the value is used. We need to handle
18424// patterns such as the following:
18425// (brcond (xor (setcc (loop.decrement), 0, ne), 1), exit)
18426// (brcond (setcc (loop.decrement), 0, eq), exit)
18427// (brcond (setcc (loop.decrement), 0, ne), header)
18429 bool &Negate) {
18430 switch (N->getOpcode()) {
18431 default:
18432 break;
18433 case ISD::XOR: {
18434 if (!isa<ConstantSDNode>(N.getOperand(1)))
18435 return SDValue();
18436 if (!cast<ConstantSDNode>(N.getOperand(1))->isOne())
18437 return SDValue();
18438 Negate = !Negate;
18439 return SearchLoopIntrinsic(N.getOperand(0), CC, Imm, Negate);
18440 }
18441 case ISD::SETCC: {
18442 auto *Const = dyn_cast<ConstantSDNode>(N.getOperand(1));
18443 if (!Const)
18444 return SDValue();
18445 if (Const->isZero())
18446 Imm = 0;
18447 else if (Const->isOne())
18448 Imm = 1;
18449 else
18450 return SDValue();
18451 CC = cast<CondCodeSDNode>(N.getOperand(2))->get();
18452 return SearchLoopIntrinsic(N->getOperand(0), CC, Imm, Negate);
18453 }
18455 unsigned IntOp = N.getConstantOperandVal(1);
18456 if (IntOp != Intrinsic::test_start_loop_iterations &&
18457 IntOp != Intrinsic::loop_decrement_reg)
18458 return SDValue();
18459 return N;
18460 }
18461 }
18462 return SDValue();
18463}
18464
18467 const ARMSubtarget *ST) {
18468
18469 // The hwloop intrinsics that we're interested are used for control-flow,
18470 // either for entering or exiting the loop:
18471 // - test.start.loop.iterations will test whether its operand is zero. If it
18472 // is zero, the proceeding branch should not enter the loop.
18473 // - loop.decrement.reg also tests whether its operand is zero. If it is
18474 // zero, the proceeding branch should not branch back to the beginning of
18475 // the loop.
18476 // So here, we need to check that how the brcond is using the result of each
18477 // of the intrinsics to ensure that we're branching to the right place at the
18478 // right time.
18479
18480 ISD::CondCode CC;
18481 SDValue Cond;
18482 int Imm = 1;
18483 bool Negate = false;
18484 SDValue Chain = N->getOperand(0);
18485 SDValue Dest;
18486
18487 if (N->getOpcode() == ISD::BRCOND) {
18488 CC = ISD::SETEQ;
18489 Cond = N->getOperand(1);
18490 Dest = N->getOperand(2);
18491 } else {
18492 assert(N->getOpcode() == ISD::BR_CC && "Expected BRCOND or BR_CC!");
18493 CC = cast<CondCodeSDNode>(N->getOperand(1))->get();
18494 Cond = N->getOperand(2);
18495 Dest = N->getOperand(4);
18496 if (auto *Const = dyn_cast<ConstantSDNode>(N->getOperand(3))) {
18497 if (!Const->isOne() && !Const->isZero())
18498 return SDValue();
18499 Imm = Const->getZExtValue();
18500 } else
18501 return SDValue();
18502 }
18503
18504 SDValue Int = SearchLoopIntrinsic(Cond, CC, Imm, Negate);
18505 if (!Int)
18506 return SDValue();
18507
18508 if (Negate)
18509 CC = ISD::getSetCCInverse(CC, /* Integer inverse */ MVT::i32);
18510
18511 auto IsTrueIfZero = [](ISD::CondCode CC, int Imm) {
18512 return (CC == ISD::SETEQ && Imm == 0) ||
18513 (CC == ISD::SETNE && Imm == 1) ||
18514 (CC == ISD::SETLT && Imm == 1) ||
18515 (CC == ISD::SETULT && Imm == 1);
18516 };
18517
18518 auto IsFalseIfZero = [](ISD::CondCode CC, int Imm) {
18519 return (CC == ISD::SETEQ && Imm == 1) ||
18520 (CC == ISD::SETNE && Imm == 0) ||
18521 (CC == ISD::SETGT && Imm == 0) ||
18522 (CC == ISD::SETUGT && Imm == 0) ||
18523 (CC == ISD::SETGE && Imm == 1) ||
18524 (CC == ISD::SETUGE && Imm == 1);
18525 };
18526
18527 assert((IsTrueIfZero(CC, Imm) || IsFalseIfZero(CC, Imm)) &&
18528 "unsupported condition");
18529
18530 SDLoc dl(Int);
18531 SelectionDAG &DAG = DCI.DAG;
18532 SDValue Elements = Int.getOperand(2);
18533 unsigned IntOp = Int->getConstantOperandVal(1);
18534 assert((N->hasOneUse() && N->user_begin()->getOpcode() == ISD::BR) &&
18535 "expected single br user");
18536 SDNode *Br = *N->user_begin();
18537 SDValue OtherTarget = Br->getOperand(1);
18538
18539 // Update the unconditional branch to branch to the given Dest.
18540 auto UpdateUncondBr = [](SDNode *Br, SDValue Dest, SelectionDAG &DAG) {
18541 SDValue NewBrOps[] = { Br->getOperand(0), Dest };
18542 SDValue NewBr = DAG.getNode(ISD::BR, SDLoc(Br), MVT::Other, NewBrOps);
18543 DAG.ReplaceAllUsesOfValueWith(SDValue(Br, 0), NewBr);
18544 };
18545
18546 if (IntOp == Intrinsic::test_start_loop_iterations) {
18547 SDValue Res;
18548 SDValue Setup = DAG.getNode(ARMISD::WLSSETUP, dl, MVT::i32, Elements);
18549 // We expect this 'instruction' to branch when the counter is zero.
18550 if (IsTrueIfZero(CC, Imm)) {
18551 SDValue Ops[] = {Chain, Setup, Dest};
18552 Res = DAG.getNode(ARMISD::WLS, dl, MVT::Other, Ops);
18553 } else {
18554 // The logic is the reverse of what we need for WLS, so find the other
18555 // basic block target: the target of the proceeding br.
18556 UpdateUncondBr(Br, Dest, DAG);
18557
18558 SDValue Ops[] = {Chain, Setup, OtherTarget};
18559 Res = DAG.getNode(ARMISD::WLS, dl, MVT::Other, Ops);
18560 }
18561 // Update LR count to the new value
18562 DAG.ReplaceAllUsesOfValueWith(Int.getValue(0), Setup);
18563 // Update chain
18564 DAG.ReplaceAllUsesOfValueWith(Int.getValue(2), Int.getOperand(0));
18565 return Res;
18566 } else {
18567 SDValue Size =
18568 DAG.getTargetConstant(Int.getConstantOperandVal(3), dl, MVT::i32);
18569 SDValue Args[] = { Int.getOperand(0), Elements, Size, };
18570 SDValue LoopDec = DAG.getNode(ARMISD::LOOP_DEC, dl,
18571 DAG.getVTList(MVT::i32, MVT::Other), Args);
18572 DAG.ReplaceAllUsesWith(Int.getNode(), LoopDec.getNode());
18573
18574 // We expect this instruction to branch when the count is not zero.
18575 SDValue Target = IsFalseIfZero(CC, Imm) ? Dest : OtherTarget;
18576
18577 // Update the unconditional branch to target the loop preheader if we've
18578 // found the condition has been reversed.
18579 if (Target == OtherTarget)
18580 UpdateUncondBr(Br, Dest, DAG);
18581
18582 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
18583 SDValue(LoopDec.getNode(), 1), Chain);
18584
18585 SDValue EndArgs[] = { Chain, SDValue(LoopDec.getNode(), 0), Target };
18586 return DAG.getNode(ARMISD::LE, dl, MVT::Other, EndArgs);
18587 }
18588 return SDValue();
18589}
18590
18591/// PerformBRCONDCombine - Target-specific DAG combining for ARMISD::BRCOND.
18592SDValue
18594 SDValue Cmp = N->getOperand(3);
18595 if (Cmp.getOpcode() != ARMISD::CMPZ)
18596 // Only looking at NE cases.
18597 return SDValue();
18598
18599 SDLoc dl(N);
18600 SDValue LHS = Cmp.getOperand(0);
18601 SDValue RHS = Cmp.getOperand(1);
18602 SDValue Chain = N->getOperand(0);
18603 SDValue BB = N->getOperand(1);
18604 SDValue ARMcc = N->getOperand(2);
18606
18607 // (brcond Chain BB ne (cmpz (and (cmov 0 1 CC Flags) 1) 0))
18608 // -> (brcond Chain BB CC Flags)
18609 if (CC == ARMCC::NE && LHS.getOpcode() == ISD::AND && LHS->hasOneUse() &&
18610 LHS->getOperand(0)->getOpcode() == ARMISD::CMOV &&
18611 LHS->getOperand(0)->hasOneUse() &&
18612 isNullConstant(LHS->getOperand(0)->getOperand(0)) &&
18613 isOneConstant(LHS->getOperand(0)->getOperand(1)) &&
18614 isOneConstant(LHS->getOperand(1)) && isNullConstant(RHS)) {
18615 return DAG.getNode(ARMISD::BRCOND, dl, MVT::Other, Chain, BB,
18616 LHS->getOperand(0)->getOperand(2),
18617 LHS->getOperand(0)->getOperand(3));
18618 }
18619
18620 return SDValue();
18621}
18622
18623/// PerformCMOVCombine - Target-specific DAG combining for ARMISD::CMOV.
18624SDValue
18626 SDLoc dl(N);
18627 EVT VT = N->getValueType(0);
18628 SDValue FalseVal = N->getOperand(0);
18629 SDValue TrueVal = N->getOperand(1);
18630 SDValue ARMcc = N->getOperand(2);
18631 SDValue Cmp = N->getOperand(3);
18632
18633 // Try to form CSINV etc.
18634 unsigned Opcode;
18635 bool InvertCond;
18636 if (SDValue CSetOp =
18637 matchCSET(Opcode, InvertCond, TrueVal, FalseVal, Subtarget)) {
18638 if (InvertCond) {
18639 ARMCC::CondCodes CondCode =
18640 (ARMCC::CondCodes)cast<const ConstantSDNode>(ARMcc)->getZExtValue();
18641 CondCode = ARMCC::getOppositeCondition(CondCode);
18642 ARMcc = DAG.getConstant(CondCode, SDLoc(ARMcc), MVT::i32);
18643 }
18644 return DAG.getNode(Opcode, dl, VT, CSetOp, CSetOp, ARMcc, Cmp);
18645 }
18646
18647 if (Cmp.getOpcode() != ARMISD::CMPZ)
18648 // Only looking at EQ and NE cases.
18649 return SDValue();
18650
18651 SDValue LHS = Cmp.getOperand(0);
18652 SDValue RHS = Cmp.getOperand(1);
18654
18655 // BFI is only available on V6T2+.
18656 if (!Subtarget->isThumb1Only() && Subtarget->hasV6T2Ops()) {
18658 if (R)
18659 return R;
18660 }
18661
18662 // Simplify
18663 // mov r1, r0
18664 // cmp r1, x
18665 // mov r0, y
18666 // moveq r0, x
18667 // to
18668 // cmp r0, x
18669 // movne r0, y
18670 //
18671 // mov r1, r0
18672 // cmp r1, x
18673 // mov r0, x
18674 // movne r0, y
18675 // to
18676 // cmp r0, x
18677 // movne r0, y
18678 /// FIXME: Turn this into a target neutral optimization?
18679 SDValue Res;
18680 if (CC == ARMCC::NE && FalseVal == RHS && FalseVal != LHS) {
18681 Res = DAG.getNode(ARMISD::CMOV, dl, VT, LHS, TrueVal, ARMcc, Cmp);
18682 } else if (CC == ARMCC::EQ && TrueVal == RHS) {
18683 SDValue ARMcc;
18684 SDValue NewCmp = getARMCmp(LHS, RHS, ISD::SETNE, ARMcc, DAG, dl);
18685 Res = DAG.getNode(ARMISD::CMOV, dl, VT, LHS, FalseVal, ARMcc, NewCmp);
18686 }
18687
18688 // (cmov F T ne (cmpz (cmov 0 1 CC Flags) 0))
18689 // -> (cmov F T CC Flags)
18690 if (CC == ARMCC::NE && LHS.getOpcode() == ARMISD::CMOV && LHS->hasOneUse() &&
18691 isNullConstant(LHS->getOperand(0)) && isOneConstant(LHS->getOperand(1)) &&
18692 isNullConstant(RHS)) {
18693 return DAG.getNode(ARMISD::CMOV, dl, VT, FalseVal, TrueVal,
18694 LHS->getOperand(2), LHS->getOperand(3));
18695 }
18696
18697 if (!VT.isInteger())
18698 return SDValue();
18699
18700 // Fold away an unnecessary CMPZ/CMOV
18701 // CMOV A, B, C1, (CMPZ (CMOV 1, 0, C2, D), 0) ->
18702 // if C1==EQ -> CMOV A, B, C2, D
18703 // if C1==NE -> CMOV A, B, NOT(C2), D
18704 if (N->getConstantOperandVal(2) == ARMCC::EQ ||
18705 N->getConstantOperandVal(2) == ARMCC::NE) {
18707 if (SDValue C = IsCMPZCSINC(N->getOperand(3).getNode(), Cond)) {
18708 if (N->getConstantOperandVal(2) == ARMCC::NE)
18710 return DAG.getNode(N->getOpcode(), SDLoc(N), MVT::i32, N->getOperand(0),
18711 N->getOperand(1),
18712 DAG.getConstant(Cond, SDLoc(N), MVT::i32), C);
18713 }
18714 }
18715
18716 // Materialize a boolean comparison for integers so we can avoid branching.
18717 if (isNullConstant(FalseVal)) {
18718 if (CC == ARMCC::EQ && isOneConstant(TrueVal)) {
18719 if (!Subtarget->isThumb1Only() && Subtarget->hasV5TOps()) {
18720 // If x == y then x - y == 0 and ARM's CLZ will return 32, shifting it
18721 // right 5 bits will make that 32 be 1, otherwise it will be 0.
18722 // CMOV 0, 1, ==, (CMPZ x, y) -> SRL (CTLZ (SUB x, y)), 5
18723 SDValue Sub = DAG.getNode(ISD::SUB, dl, VT, LHS, RHS);
18724 Res = DAG.getNode(ISD::SRL, dl, VT, DAG.getNode(ISD::CTLZ, dl, VT, Sub),
18725 DAG.getConstant(5, dl, MVT::i32));
18726 } else {
18727 // CMOV 0, 1, ==, (CMPZ x, y) ->
18728 // (UADDO_CARRY (SUB x, y), t:0, t:1)
18729 // where t = (USUBO_CARRY 0, (SUB x, y), 0)
18730 //
18731 // The USUBO_CARRY computes 0 - (x - y) and this will give a borrow when
18732 // x != y. In other words, a carry C == 1 when x == y, C == 0
18733 // otherwise.
18734 // The final UADDO_CARRY computes
18735 // x - y + (0 - (x - y)) + C == C
18736 SDValue Sub = DAG.getNode(ISD::SUB, dl, VT, LHS, RHS);
18737 SDVTList VTs = DAG.getVTList(VT, MVT::i32);
18738 SDValue Neg = DAG.getNode(ISD::USUBO, dl, VTs, FalseVal, Sub);
18739 // ISD::USUBO_CARRY returns a borrow but we want the carry here
18740 // actually.
18741 SDValue Carry =
18742 DAG.getNode(ISD::SUB, dl, MVT::i32,
18743 DAG.getConstant(1, dl, MVT::i32), Neg.getValue(1));
18744 Res = DAG.getNode(ISD::UADDO_CARRY, dl, VTs, Sub, Neg, Carry);
18745 }
18746 } else if (CC == ARMCC::NE && !isNullConstant(RHS) &&
18747 (!Subtarget->isThumb1Only() || isPowerOf2Constant(TrueVal))) {
18748 // This seems pointless but will allow us to combine it further below.
18749 // CMOV 0, z, !=, (CMPZ x, y) -> CMOV (SUBC x, y), z, !=, (SUBC x, y):1
18750 SDValue Sub =
18751 DAG.getNode(ARMISD::SUBC, dl, DAG.getVTList(VT, MVT::i32), LHS, RHS);
18752 Res = DAG.getNode(ARMISD::CMOV, dl, VT, Sub, TrueVal, ARMcc,
18753 Sub.getValue(1));
18754 FalseVal = Sub;
18755 }
18756 } else if (isNullConstant(TrueVal)) {
18757 if (CC == ARMCC::EQ && !isNullConstant(RHS) &&
18758 (!Subtarget->isThumb1Only() || isPowerOf2Constant(FalseVal))) {
18759 // This seems pointless but will allow us to combine it further below
18760 // Note that we change == for != as this is the dual for the case above.
18761 // CMOV z, 0, ==, (CMPZ x, y) -> CMOV (SUBC x, y), z, !=, (SUBC x, y):1
18762 SDValue Sub =
18763 DAG.getNode(ARMISD::SUBC, dl, DAG.getVTList(VT, MVT::i32), LHS, RHS);
18764 Res = DAG.getNode(ARMISD::CMOV, dl, VT, Sub, FalseVal,
18765 DAG.getConstant(ARMCC::NE, dl, MVT::i32),
18766 Sub.getValue(1));
18767 FalseVal = Sub;
18768 }
18769 }
18770
18771 // On Thumb1, the DAG above may be further combined if z is a power of 2
18772 // (z == 2 ^ K).
18773 // CMOV (SUBC x, y), z, !=, (SUBC x, y):1 ->
18774 // t1 = (USUBO (SUB x, y), 1)
18775 // t2 = (USUBO_CARRY (SUB x, y), t1:0, t1:1)
18776 // Result = if K != 0 then (SHL t2:0, K) else t2:0
18777 //
18778 // This also handles the special case of comparing against zero; it's
18779 // essentially, the same pattern, except there's no SUBC:
18780 // CMOV x, z, !=, (CMPZ x, 0) ->
18781 // t1 = (USUBO x, 1)
18782 // t2 = (USUBO_CARRY x, t1:0, t1:1)
18783 // Result = if K != 0 then (SHL t2:0, K) else t2:0
18784 const APInt *TrueConst;
18785 if (Subtarget->isThumb1Only() && CC == ARMCC::NE &&
18786 ((FalseVal.getOpcode() == ARMISD::SUBC && FalseVal.getOperand(0) == LHS &&
18787 FalseVal.getOperand(1) == RHS) ||
18788 (FalseVal == LHS && isNullConstant(RHS))) &&
18789 (TrueConst = isPowerOf2Constant(TrueVal))) {
18790 SDVTList VTs = DAG.getVTList(VT, MVT::i32);
18791 unsigned ShiftAmount = TrueConst->logBase2();
18792 if (ShiftAmount)
18793 TrueVal = DAG.getConstant(1, dl, VT);
18794 SDValue Subc = DAG.getNode(ISD::USUBO, dl, VTs, FalseVal, TrueVal);
18795 Res = DAG.getNode(ISD::USUBO_CARRY, dl, VTs, FalseVal, Subc,
18796 Subc.getValue(1));
18797
18798 if (ShiftAmount)
18799 Res = DAG.getNode(ISD::SHL, dl, VT, Res,
18800 DAG.getConstant(ShiftAmount, dl, MVT::i32));
18801 }
18802
18803 if (Res.getNode()) {
18805 // Capture demanded bits information that would be otherwise lost.
18806 if (Known.Zero == 0xfffffffe)
18807 Res = DAG.getNode(ISD::AssertZext, dl, MVT::i32, Res,
18808 DAG.getValueType(MVT::i1));
18809 else if (Known.Zero == 0xffffff00)
18810 Res = DAG.getNode(ISD::AssertZext, dl, MVT::i32, Res,
18811 DAG.getValueType(MVT::i8));
18812 else if (Known.Zero == 0xffff0000)
18813 Res = DAG.getNode(ISD::AssertZext, dl, MVT::i32, Res,
18814 DAG.getValueType(MVT::i16));
18815 }
18816
18817 return Res;
18818}
18819
18822 const ARMSubtarget *ST) {
18823 SelectionDAG &DAG = DCI.DAG;
18824 SDValue Src = N->getOperand(0);
18825 EVT DstVT = N->getValueType(0);
18826
18827 // Convert v4f32 bitcast (v4i32 vdup (i32)) -> v4f32 vdup (i32) under MVE.
18828 if (ST->hasMVEIntegerOps() && Src.getOpcode() == ARMISD::VDUP) {
18829 EVT SrcVT = Src.getValueType();
18830 if (SrcVT.getScalarSizeInBits() == DstVT.getScalarSizeInBits())
18831 return DAG.getNode(ARMISD::VDUP, SDLoc(N), DstVT, Src.getOperand(0));
18832 }
18833
18834 // We may have a bitcast of something that has already had this bitcast
18835 // combine performed on it, so skip past any VECTOR_REG_CASTs.
18836 if (Src.getOpcode() == ARMISD::VECTOR_REG_CAST &&
18837 Src.getOperand(0).getValueType().getScalarSizeInBits() <=
18838 Src.getValueType().getScalarSizeInBits())
18839 Src = Src.getOperand(0);
18840
18841 // Bitcast from element-wise VMOV or VMVN doesn't need VREV if the VREV that
18842 // would be generated is at least the width of the element type.
18843 EVT SrcVT = Src.getValueType();
18844 if ((Src.getOpcode() == ARMISD::VMOVIMM ||
18845 Src.getOpcode() == ARMISD::VMVNIMM ||
18846 Src.getOpcode() == ARMISD::VMOVFPIMM) &&
18847 SrcVT.getScalarSizeInBits() <= DstVT.getScalarSizeInBits() &&
18848 DAG.getDataLayout().isBigEndian())
18849 return DAG.getNode(ARMISD::VECTOR_REG_CAST, SDLoc(N), DstVT, Src);
18850
18851 // bitcast(extract(x, n)); bitcast(extract(x, n+1)) -> VMOVRRD x
18852 if (SDValue R = PerformExtractEltToVMOVRRD(N, DCI))
18853 return R;
18854
18855 return SDValue();
18856}
18857
18858// Some combines for the MVETrunc truncations legalizer helper. Also lowers the
18859// node into stack operations after legalizeOps.
18862 SelectionDAG &DAG = DCI.DAG;
18863 EVT VT = N->getValueType(0);
18864 SDLoc DL(N);
18865
18866 // MVETrunc(Undef, Undef) -> Undef
18867 if (all_of(N->ops(), [](SDValue Op) { return Op.isUndef(); }))
18868 return DAG.getUNDEF(VT);
18869
18870 // MVETrunc(MVETrunc a b, MVETrunc c, d) -> MVETrunc
18871 if (N->getNumOperands() == 2 &&
18872 N->getOperand(0).getOpcode() == ARMISD::MVETRUNC &&
18873 N->getOperand(1).getOpcode() == ARMISD::MVETRUNC)
18874 return DAG.getNode(ARMISD::MVETRUNC, DL, VT, N->getOperand(0).getOperand(0),
18875 N->getOperand(0).getOperand(1),
18876 N->getOperand(1).getOperand(0),
18877 N->getOperand(1).getOperand(1));
18878
18879 // MVETrunc(shuffle, shuffle) -> VMOVN
18880 if (N->getNumOperands() == 2 &&
18881 N->getOperand(0).getOpcode() == ISD::VECTOR_SHUFFLE &&
18882 N->getOperand(1).getOpcode() == ISD::VECTOR_SHUFFLE) {
18883 auto *S0 = cast<ShuffleVectorSDNode>(N->getOperand(0).getNode());
18884 auto *S1 = cast<ShuffleVectorSDNode>(N->getOperand(1).getNode());
18885
18886 if (S0->getOperand(0) == S1->getOperand(0) &&
18887 S0->getOperand(1) == S1->getOperand(1)) {
18888 // Construct complete shuffle mask
18889 SmallVector<int, 8> Mask(S0->getMask());
18890 Mask.append(S1->getMask().begin(), S1->getMask().end());
18891
18892 if (isVMOVNTruncMask(Mask, VT, false))
18893 return DAG.getNode(
18894 ARMISD::VMOVN, DL, VT,
18895 DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, VT, S0->getOperand(0)),
18896 DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, VT, S0->getOperand(1)),
18897 DAG.getConstant(1, DL, MVT::i32));
18898 if (isVMOVNTruncMask(Mask, VT, true))
18899 return DAG.getNode(
18900 ARMISD::VMOVN, DL, VT,
18901 DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, VT, S0->getOperand(1)),
18902 DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, VT, S0->getOperand(0)),
18903 DAG.getConstant(1, DL, MVT::i32));
18904 }
18905 }
18906
18907 // For MVETrunc of a buildvector or shuffle, it can be beneficial to lower the
18908 // truncate to a buildvector to allow the generic optimisations to kick in.
18909 if (all_of(N->ops(), [](SDValue Op) {
18910 return Op.getOpcode() == ISD::BUILD_VECTOR ||
18911 Op.getOpcode() == ISD::VECTOR_SHUFFLE ||
18912 (Op.getOpcode() == ISD::BITCAST &&
18913 Op.getOperand(0).getOpcode() == ISD::BUILD_VECTOR);
18914 })) {
18915 SmallVector<SDValue, 8> Extracts;
18916 for (unsigned Op = 0; Op < N->getNumOperands(); Op++) {
18917 SDValue O = N->getOperand(Op);
18918 for (unsigned i = 0; i < O.getValueType().getVectorNumElements(); i++) {
18919 SDValue Ext = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::i32, O,
18920 DAG.getConstant(i, DL, MVT::i32));
18921 Extracts.push_back(Ext);
18922 }
18923 }
18924 return DAG.getBuildVector(VT, DL, Extracts);
18925 }
18926
18927 // If we are late in the legalization process and nothing has optimised
18928 // the trunc to anything better, lower it to a stack store and reload,
18929 // performing the truncation whilst keeping the lanes in the correct order:
18930 // VSTRH.32 a, stack; VSTRH.32 b, stack+8; VLDRW.32 stack;
18931 if (!DCI.isAfterLegalizeDAG())
18932 return SDValue();
18933
18934 SDValue StackPtr = DAG.CreateStackTemporary(TypeSize::getFixed(16), Align(4));
18935 int SPFI = cast<FrameIndexSDNode>(StackPtr.getNode())->getIndex();
18936 int NumIns = N->getNumOperands();
18937 assert((NumIns == 2 || NumIns == 4) &&
18938 "Expected 2 or 4 inputs to an MVETrunc");
18939 EVT StoreVT = VT.getHalfNumVectorElementsVT(*DAG.getContext());
18940 if (N->getNumOperands() == 4)
18941 StoreVT = StoreVT.getHalfNumVectorElementsVT(*DAG.getContext());
18942
18943 SmallVector<SDValue> Chains;
18944 for (int I = 0; I < NumIns; I++) {
18945 SDValue Ptr = DAG.getNode(
18946 ISD::ADD, DL, StackPtr.getValueType(), StackPtr,
18947 DAG.getConstant(I * 16 / NumIns, DL, StackPtr.getValueType()));
18949 DAG.getMachineFunction(), SPFI, I * 16 / NumIns);
18950 SDValue Ch = DAG.getTruncStore(DAG.getEntryNode(), DL, N->getOperand(I),
18951 Ptr, MPI, StoreVT, Align(4));
18952 Chains.push_back(Ch);
18953 }
18954
18955 SDValue Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Chains);
18956 MachinePointerInfo MPI =
18958 return DAG.getLoad(VT, DL, Chain, StackPtr, MPI, Align(4));
18959}
18960
18961// Take a MVEEXT(load x) and split that into (extload x, extload x+8)
18963 SelectionDAG &DAG) {
18964 SDValue N0 = N->getOperand(0);
18966 if (!LD || !LD->isSimple() || !N0.hasOneUse() || LD->isIndexed())
18967 return SDValue();
18968
18969 EVT FromVT = LD->getMemoryVT();
18970 EVT ToVT = N->getValueType(0);
18971 if (!ToVT.isVector())
18972 return SDValue();
18973 assert(FromVT.getVectorNumElements() == ToVT.getVectorNumElements() * 2);
18974 EVT ToEltVT = ToVT.getVectorElementType();
18975 EVT FromEltVT = FromVT.getVectorElementType();
18976
18977 unsigned NumElements = 0;
18978 if (ToEltVT == MVT::i32 && (FromEltVT == MVT::i16 || FromEltVT == MVT::i8))
18979 NumElements = 4;
18980 if (ToEltVT == MVT::i16 && FromEltVT == MVT::i8)
18981 NumElements = 8;
18982 assert(NumElements != 0);
18983
18984 ISD::LoadExtType NewExtType =
18985 N->getOpcode() == ARMISD::MVESEXT ? ISD::SEXTLOAD : ISD::ZEXTLOAD;
18986 if (LD->getExtensionType() != ISD::NON_EXTLOAD &&
18987 LD->getExtensionType() != ISD::EXTLOAD &&
18988 LD->getExtensionType() != NewExtType)
18989 return SDValue();
18990
18991 LLVMContext &C = *DAG.getContext();
18992 SDLoc DL(LD);
18993 // Details about the old load
18994 SDValue Ch = LD->getChain();
18995 SDValue BasePtr = LD->getBasePtr();
18996 Align Alignment = LD->getBaseAlign();
18997 MachineMemOperand::Flags MMOFlags = LD->getMemOperand()->getFlags();
18998 AAMDNodes AAInfo = LD->getAAInfo();
18999
19000 SDValue Offset = DAG.getPOISON(BasePtr.getValueType());
19001 EVT NewFromVT = EVT::getVectorVT(
19002 C, EVT::getIntegerVT(C, FromEltVT.getScalarSizeInBits()), NumElements);
19003 EVT NewToVT = EVT::getVectorVT(
19004 C, EVT::getIntegerVT(C, ToEltVT.getScalarSizeInBits()), NumElements);
19005
19008 for (unsigned i = 0; i < FromVT.getVectorNumElements() / NumElements; i++) {
19009 unsigned NewOffset = (i * NewFromVT.getSizeInBits()) / 8;
19010 SDValue NewPtr =
19011 DAG.getObjectPtrOffset(DL, BasePtr, TypeSize::getFixed(NewOffset));
19012
19013 SDValue NewLoad =
19014 DAG.getLoad(ISD::UNINDEXED, NewExtType, NewToVT, DL, Ch, NewPtr, Offset,
19015 LD->getPointerInfo().getWithOffset(NewOffset), NewFromVT,
19016 Alignment, MMOFlags, AAInfo);
19017 Loads.push_back(NewLoad);
19018 Chains.push_back(SDValue(NewLoad.getNode(), 1));
19019 }
19020
19021 SDValue NewChain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Chains);
19022 DAG.ReplaceAllUsesOfValueWith(SDValue(LD, 1), NewChain);
19023 return DAG.getMergeValues(Loads, DL);
19024}
19025
19026// Perform combines for MVEEXT. If it has not be optimized to anything better
19027// before lowering, it gets converted to stack store and extloads performing the
19028// extend whilst still keeping the same lane ordering.
19031 SelectionDAG &DAG = DCI.DAG;
19032 EVT VT = N->getValueType(0);
19033 SDLoc DL(N);
19034 assert(N->getNumValues() == 2 && "Expected MVEEXT with 2 elements");
19035 assert((VT == MVT::v4i32 || VT == MVT::v8i16) && "Unexpected MVEEXT type");
19036
19037 EVT ExtVT = N->getOperand(0).getValueType().getHalfNumVectorElementsVT(
19038 *DAG.getContext());
19039 auto Extend = [&](SDValue V) {
19040 SDValue VVT = DAG.getNode(ARMISD::VECTOR_REG_CAST, DL, VT, V);
19041 return N->getOpcode() == ARMISD::MVESEXT
19042 ? DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, VT, VVT,
19043 DAG.getValueType(ExtVT))
19044 : DAG.getZeroExtendInReg(VVT, DL, ExtVT);
19045 };
19046
19047 // MVEEXT(VDUP) -> SIGN_EXTEND_INREG(VDUP)
19048 if (N->getOperand(0).getOpcode() == ARMISD::VDUP) {
19049 SDValue Ext = Extend(N->getOperand(0));
19050 return DAG.getMergeValues({Ext, Ext}, DL);
19051 }
19052
19053 // MVEEXT(shuffle) -> SIGN_EXTEND_INREG/ZERO_EXTEND_INREG
19054 if (auto *SVN = dyn_cast<ShuffleVectorSDNode>(N->getOperand(0))) {
19055 ArrayRef<int> Mask = SVN->getMask();
19056 assert(Mask.size() == 2 * VT.getVectorNumElements());
19057 assert(Mask.size() == SVN->getValueType(0).getVectorNumElements());
19058 unsigned Rev = VT == MVT::v4i32 ? ARMISD::VREV32 : ARMISD::VREV16;
19059 SDValue Op0 = SVN->getOperand(0);
19060 SDValue Op1 = SVN->getOperand(1);
19061
19062 auto CheckInregMask = [&](int Start, int Offset) {
19063 for (int Idx = 0, E = VT.getVectorNumElements(); Idx < E; ++Idx)
19064 if (Mask[Start + Idx] >= 0 && Mask[Start + Idx] != Idx * 2 + Offset)
19065 return false;
19066 return true;
19067 };
19068 SDValue V0 = SDValue(N, 0);
19069 SDValue V1 = SDValue(N, 1);
19070 if (CheckInregMask(0, 0))
19071 V0 = Extend(Op0);
19072 else if (CheckInregMask(0, 1))
19073 V0 = Extend(DAG.getNode(Rev, DL, SVN->getValueType(0), Op0));
19074 else if (CheckInregMask(0, Mask.size()))
19075 V0 = Extend(Op1);
19076 else if (CheckInregMask(0, Mask.size() + 1))
19077 V0 = Extend(DAG.getNode(Rev, DL, SVN->getValueType(0), Op1));
19078
19079 if (CheckInregMask(VT.getVectorNumElements(), Mask.size()))
19080 V1 = Extend(Op1);
19081 else if (CheckInregMask(VT.getVectorNumElements(), Mask.size() + 1))
19082 V1 = Extend(DAG.getNode(Rev, DL, SVN->getValueType(0), Op1));
19083 else if (CheckInregMask(VT.getVectorNumElements(), 0))
19084 V1 = Extend(Op0);
19085 else if (CheckInregMask(VT.getVectorNumElements(), 1))
19086 V1 = Extend(DAG.getNode(Rev, DL, SVN->getValueType(0), Op0));
19087
19088 if (V0.getNode() != N || V1.getNode() != N)
19089 return DAG.getMergeValues({V0, V1}, DL);
19090 }
19091
19092 // MVEEXT(load) -> extload, extload
19093 if (N->getOperand(0)->getOpcode() == ISD::LOAD)
19095 return L;
19096
19097 if (!DCI.isAfterLegalizeDAG())
19098 return SDValue();
19099
19100 // Lower to a stack store and reload:
19101 // VSTRW.32 a, stack; VLDRH.32 stack; VLDRH.32 stack+8;
19102 SDValue StackPtr = DAG.CreateStackTemporary(TypeSize::getFixed(16), Align(4));
19103 int SPFI = cast<FrameIndexSDNode>(StackPtr.getNode())->getIndex();
19104 int NumOuts = N->getNumValues();
19105 assert((NumOuts == 2 || NumOuts == 4) &&
19106 "Expected 2 or 4 outputs to an MVEEXT");
19107 EVT LoadVT = N->getOperand(0).getValueType().getHalfNumVectorElementsVT(
19108 *DAG.getContext());
19109 if (N->getNumOperands() == 4)
19110 LoadVT = LoadVT.getHalfNumVectorElementsVT(*DAG.getContext());
19111
19112 MachinePointerInfo MPI =
19114 SDValue Chain = DAG.getStore(DAG.getEntryNode(), DL, N->getOperand(0),
19115 StackPtr, MPI, Align(4));
19116
19118 for (int I = 0; I < NumOuts; I++) {
19119 SDValue Ptr = DAG.getNode(
19120 ISD::ADD, DL, StackPtr.getValueType(), StackPtr,
19121 DAG.getConstant(I * 16 / NumOuts, DL, StackPtr.getValueType()));
19123 DAG.getMachineFunction(), SPFI, I * 16 / NumOuts);
19124 SDValue Load = DAG.getExtLoad(
19125 N->getOpcode() == ARMISD::MVESEXT ? ISD::SEXTLOAD : ISD::ZEXTLOAD, DL,
19126 VT, Chain, Ptr, MPI, LoadVT, Align(4));
19127 Loads.push_back(Load);
19128 }
19129
19130 return DAG.getMergeValues(Loads, DL);
19131}
19132
19134 DAGCombinerInfo &DCI) const {
19135 switch (N->getOpcode()) {
19136 default: break;
19137 case ISD::SELECT_CC:
19138 case ISD::SELECT: return PerformSELECTCombine(N, DCI, Subtarget);
19139 case ISD::VSELECT: return PerformVSELECTCombine(N, DCI, Subtarget);
19140 case ISD::SETCC: return PerformVSetCCToVCTPCombine(N, DCI, Subtarget);
19141 case ARMISD::ADDE: return PerformADDECombine(N, DCI, Subtarget);
19142 case ARMISD::UMLAL: return PerformUMLALCombine(N, DCI.DAG, Subtarget);
19143 case ISD::ADD: return PerformADDCombine(N, DCI, Subtarget);
19144 case ISD::SUB: return PerformSUBCombine(N, DCI, Subtarget);
19145 case ISD::MUL: return PerformMULCombine(N, DCI, Subtarget);
19146 case ISD::OR: return PerformORCombine(N, DCI, Subtarget);
19147 case ISD::XOR: return PerformXORCombine(N, DCI, Subtarget);
19148 case ISD::AND: return PerformANDCombine(N, DCI, Subtarget);
19149 case ISD::BRCOND:
19150 case ISD::BR_CC: return PerformHWLoopCombine(N, DCI, Subtarget);
19151 case ARMISD::ADDC:
19152 case ARMISD::SUBC: return PerformAddcSubcCombine(N, DCI, Subtarget);
19153 case ARMISD::SUBE: return PerformAddeSubeCombine(N, DCI, Subtarget);
19154 case ARMISD::BFI: return PerformBFICombine(N, DCI.DAG);
19155 case ARMISD::VMOVRRD: return PerformVMOVRRDCombine(N, DCI, Subtarget);
19156 case ARMISD::VMOVDRR: return PerformVMOVDRRCombine(N, DCI.DAG);
19157 case ARMISD::VMOVhr: return PerformVMOVhrCombine(N, DCI);
19158 case ARMISD::VMOVrh: return PerformVMOVrhCombine(N, DCI.DAG);
19159 case ISD::STORE: return PerformSTORECombine(N, DCI, Subtarget);
19160 case ISD::BUILD_VECTOR: return PerformBUILD_VECTORCombine(N, DCI, Subtarget);
19163 return PerformExtractEltCombine(N, DCI, Subtarget);
19167 case ARMISD::VDUPLANE: return PerformVDUPLANECombine(N, DCI, Subtarget);
19168 case ARMISD::VDUP: return PerformVDUPCombine(N, DCI.DAG, Subtarget);
19169 case ISD::FP_TO_SINT:
19170 case ISD::FP_TO_UINT:
19171 return PerformVCVTCombine(N, DCI.DAG, Subtarget);
19172 case ISD::FADD:
19173 return PerformFADDCombine(N, DCI.DAG, Subtarget);
19174 case ISD::FMUL:
19175 return PerformVMulVCTPCombine(N, DCI.DAG, Subtarget);
19177 return PerformIntrinsicCombine(N, DCI);
19178 case ISD::SHL:
19179 case ISD::SRA:
19180 case ISD::SRL:
19181 return PerformShiftCombine(N, DCI, Subtarget);
19182 case ISD::SIGN_EXTEND:
19183 case ISD::ZERO_EXTEND:
19184 case ISD::ANY_EXTEND:
19185 return PerformExtendCombine(N, DCI.DAG, Subtarget);
19186 case ISD::FP_EXTEND:
19187 return PerformFPExtendCombine(N, DCI.DAG, Subtarget);
19188 case ISD::SMIN:
19189 case ISD::UMIN:
19190 case ISD::SMAX:
19191 case ISD::UMAX:
19192 return PerformMinMaxCombine(N, DCI.DAG, Subtarget);
19193 case ARMISD::CMOV:
19194 return PerformCMOVCombine(N, DCI.DAG);
19195 case ARMISD::BRCOND:
19196 return PerformBRCONDCombine(N, DCI.DAG);
19197 case ARMISD::CMPZ:
19198 return PerformCMPZCombine(N, DCI.DAG);
19199 case ARMISD::CSINC:
19200 case ARMISD::CSINV:
19201 case ARMISD::CSNEG:
19202 return PerformCSETCombine(N, DCI.DAG);
19203 case ISD::LOAD:
19204 return PerformLOADCombine(N, DCI, Subtarget);
19205 case ARMISD::VLD1DUP:
19206 case ARMISD::VLD2DUP:
19207 case ARMISD::VLD3DUP:
19208 case ARMISD::VLD4DUP:
19209 return PerformVLDCombine(N, DCI);
19211 return PerformARMBUILD_VECTORCombine(N, DCI);
19212 case ISD::BITCAST:
19213 return PerformBITCASTCombine(N, DCI, Subtarget);
19214 case ARMISD::PREDICATE_CAST:
19215 return PerformPREDICATE_CASTCombine(N, DCI);
19216 case ARMISD::VECTOR_REG_CAST:
19217 return PerformVECTOR_REG_CASTCombine(N, DCI.DAG, Subtarget);
19218 case ARMISD::MVETRUNC:
19219 return PerformMVETruncCombine(N, DCI);
19220 case ARMISD::MVESEXT:
19221 case ARMISD::MVEZEXT:
19222 return PerformMVEExtCombine(N, DCI);
19223 case ARMISD::VCMP:
19224 return PerformVCMPCombine(N, DCI.DAG, Subtarget);
19225 case ISD::VECREDUCE_ADD:
19226 return PerformVECREDUCE_ADDCombine(N, DCI.DAG, Subtarget);
19227 case ARMISD::VADDVs:
19228 case ARMISD::VADDVu:
19229 case ARMISD::VADDLVs:
19230 case ARMISD::VADDLVu:
19231 case ARMISD::VADDLVAs:
19232 case ARMISD::VADDLVAu:
19233 case ARMISD::VMLAVs:
19234 case ARMISD::VMLAVu:
19235 case ARMISD::VMLALVs:
19236 case ARMISD::VMLALVu:
19237 case ARMISD::VMLALVAs:
19238 case ARMISD::VMLALVAu:
19239 return PerformReduceShuffleCombine(N, DCI.DAG);
19240 case ARMISD::VMOVN:
19241 return PerformVMOVNCombine(N, DCI);
19242 case ARMISD::VQMOVNs:
19243 case ARMISD::VQMOVNu:
19244 return PerformVQMOVNCombine(N, DCI);
19245 case ARMISD::VQDMULH:
19246 return PerformVQDMULHCombine(N, DCI);
19247 case ARMISD::ASRL:
19248 case ARMISD::LSRL:
19249 case ARMISD::LSLL:
19250 return PerformLongShiftCombine(N, DCI.DAG);
19251 case ARMISD::SMULWB: {
19252 unsigned BitWidth = N->getValueType(0).getSizeInBits();
19253 APInt DemandedMask = APInt::getLowBitsSet(BitWidth, 16);
19254 if (SimplifyDemandedBits(N->getOperand(1), DemandedMask, DCI))
19255 return SDValue();
19256 break;
19257 }
19258 case ARMISD::SMULWT: {
19259 unsigned BitWidth = N->getValueType(0).getSizeInBits();
19260 APInt DemandedMask = APInt::getHighBitsSet(BitWidth, 16);
19261 if (SimplifyDemandedBits(N->getOperand(1), DemandedMask, DCI))
19262 return SDValue();
19263 break;
19264 }
19265 case ARMISD::SMLALBB:
19266 case ARMISD::QADD16b:
19267 case ARMISD::QSUB16b:
19268 case ARMISD::UQADD16b:
19269 case ARMISD::UQSUB16b: {
19270 unsigned BitWidth = N->getValueType(0).getSizeInBits();
19271 APInt DemandedMask = APInt::getLowBitsSet(BitWidth, 16);
19272 if ((SimplifyDemandedBits(N->getOperand(0), DemandedMask, DCI)) ||
19273 (SimplifyDemandedBits(N->getOperand(1), DemandedMask, DCI)))
19274 return SDValue();
19275 break;
19276 }
19277 case ARMISD::SMLALBT: {
19278 unsigned LowWidth = N->getOperand(0).getValueType().getSizeInBits();
19279 APInt LowMask = APInt::getLowBitsSet(LowWidth, 16);
19280 unsigned HighWidth = N->getOperand(1).getValueType().getSizeInBits();
19281 APInt HighMask = APInt::getHighBitsSet(HighWidth, 16);
19282 if ((SimplifyDemandedBits(N->getOperand(0), LowMask, DCI)) ||
19283 (SimplifyDemandedBits(N->getOperand(1), HighMask, DCI)))
19284 return SDValue();
19285 break;
19286 }
19287 case ARMISD::SMLALTB: {
19288 unsigned HighWidth = N->getOperand(0).getValueType().getSizeInBits();
19289 APInt HighMask = APInt::getHighBitsSet(HighWidth, 16);
19290 unsigned LowWidth = N->getOperand(1).getValueType().getSizeInBits();
19291 APInt LowMask = APInt::getLowBitsSet(LowWidth, 16);
19292 if ((SimplifyDemandedBits(N->getOperand(0), HighMask, DCI)) ||
19293 (SimplifyDemandedBits(N->getOperand(1), LowMask, DCI)))
19294 return SDValue();
19295 break;
19296 }
19297 case ARMISD::SMLALTT: {
19298 unsigned BitWidth = N->getValueType(0).getSizeInBits();
19299 APInt DemandedMask = APInt::getHighBitsSet(BitWidth, 16);
19300 if ((SimplifyDemandedBits(N->getOperand(0), DemandedMask, DCI)) ||
19301 (SimplifyDemandedBits(N->getOperand(1), DemandedMask, DCI)))
19302 return SDValue();
19303 break;
19304 }
19305 case ARMISD::QADD8b:
19306 case ARMISD::QSUB8b:
19307 case ARMISD::UQADD8b:
19308 case ARMISD::UQSUB8b: {
19309 unsigned BitWidth = N->getValueType(0).getSizeInBits();
19310 APInt DemandedMask = APInt::getLowBitsSet(BitWidth, 8);
19311 if ((SimplifyDemandedBits(N->getOperand(0), DemandedMask, DCI)) ||
19312 (SimplifyDemandedBits(N->getOperand(1), DemandedMask, DCI)))
19313 return SDValue();
19314 break;
19315 }
19316 case ARMISD::VBSP:
19317 if (N->getOperand(1) == N->getOperand(2))
19318 return N->getOperand(1);
19319 return SDValue();
19322 switch (N->getConstantOperandVal(1)) {
19323 case Intrinsic::arm_neon_vld1:
19324 case Intrinsic::arm_neon_vld1x2:
19325 case Intrinsic::arm_neon_vld1x3:
19326 case Intrinsic::arm_neon_vld1x4:
19327 case Intrinsic::arm_neon_vld2:
19328 case Intrinsic::arm_neon_vld3:
19329 case Intrinsic::arm_neon_vld4:
19330 case Intrinsic::arm_neon_vld2lane:
19331 case Intrinsic::arm_neon_vld3lane:
19332 case Intrinsic::arm_neon_vld4lane:
19333 case Intrinsic::arm_neon_vld2dup:
19334 case Intrinsic::arm_neon_vld3dup:
19335 case Intrinsic::arm_neon_vld4dup:
19336 case Intrinsic::arm_neon_vst1:
19337 case Intrinsic::arm_neon_vst1x2:
19338 case Intrinsic::arm_neon_vst1x3:
19339 case Intrinsic::arm_neon_vst1x4:
19340 case Intrinsic::arm_neon_vst2:
19341 case Intrinsic::arm_neon_vst3:
19342 case Intrinsic::arm_neon_vst4:
19343 case Intrinsic::arm_neon_vst2lane:
19344 case Intrinsic::arm_neon_vst3lane:
19345 case Intrinsic::arm_neon_vst4lane:
19346 return PerformVLDCombine(N, DCI);
19347 case Intrinsic::arm_mve_vld2q:
19348 case Intrinsic::arm_mve_vld4q:
19349 case Intrinsic::arm_mve_vst2q:
19350 case Intrinsic::arm_mve_vst4q:
19351 return PerformMVEVLDCombine(N, DCI);
19352 default: break;
19353 }
19354 break;
19355 }
19356 return SDValue();
19357}
19358
19360 EVT VT) const {
19361 return (VT == MVT::f32) && (Opc == ISD::LOAD || Opc == ISD::STORE);
19362}
19363
19365 Align Alignment,
19367 unsigned *Fast) const {
19368 // Depends what it gets converted into if the type is weird.
19369 if (!VT.isSimple())
19370 return false;
19371
19372 // The AllowsUnaligned flag models the SCTLR.A setting in ARM cpus
19373 bool AllowsUnaligned = Subtarget->allowsUnalignedMem();
19374 auto Ty = VT.getSimpleVT().SimpleTy;
19375
19376 if (Ty == MVT::i8 || Ty == MVT::i16 || Ty == MVT::i32) {
19377 // Unaligned access can use (for example) LRDB, LRDH, LDR
19378 if (AllowsUnaligned) {
19379 if (Fast)
19380 *Fast = Subtarget->hasV7Ops();
19381 return true;
19382 }
19383 }
19384
19385 if (Ty == MVT::f64 || Ty == MVT::v2f64) {
19386 // For any little-endian targets with neon, we can support unaligned ld/st
19387 // of D and Q (e.g. {D0,D1}) registers by using vld1.i8/vst1.i8.
19388 // A big-endian target may also explicitly support unaligned accesses
19389 if (Subtarget->hasNEON() && (AllowsUnaligned || Subtarget->isLittle())) {
19390 if (Fast)
19391 *Fast = 1;
19392 return true;
19393 }
19394 }
19395
19396 if (!Subtarget->hasMVEIntegerOps())
19397 return false;
19398
19399 // These are for predicates
19400 if ((Ty == MVT::v16i1 || Ty == MVT::v8i1 || Ty == MVT::v4i1 ||
19401 Ty == MVT::v2i1)) {
19402 if (Fast)
19403 *Fast = 1;
19404 return true;
19405 }
19406
19407 // These are for truncated stores/narrowing loads. They are fine so long as
19408 // the alignment is at least the size of the item being loaded
19409 if ((Ty == MVT::v4i8 || Ty == MVT::v8i8 || Ty == MVT::v4i16) &&
19410 Alignment >= VT.getScalarSizeInBits() / 8) {
19411 if (Fast)
19412 *Fast = true;
19413 return true;
19414 }
19415
19416 // In little-endian MVE, the store instructions VSTRB.U8, VSTRH.U16 and
19417 // VSTRW.U32 all store the vector register in exactly the same format, and
19418 // differ only in the range of their immediate offset field and the required
19419 // alignment. So there is always a store that can be used, regardless of
19420 // actual type.
19421 //
19422 // For big endian, that is not the case. But can still emit a (VSTRB.U8;
19423 // VREV64.8) pair and get the same effect. This will likely be better than
19424 // aligning the vector through the stack.
19425 if (Ty == MVT::v16i8 || Ty == MVT::v8i16 || Ty == MVT::v8f16 ||
19426 Ty == MVT::v4i32 || Ty == MVT::v4f32 || Ty == MVT::v2i64 ||
19427 Ty == MVT::v2f64) {
19428 if (Fast)
19429 *Fast = 1;
19430 return true;
19431 }
19432
19433 return false;
19434}
19435
19437 LLVMContext &Context, const MemOp &Op,
19438 const AttributeList &FuncAttributes) const {
19439 // See if we can use NEON instructions for this...
19440 if ((Op.isMemcpyOrMemmove() || Op.isZeroMemset()) && Subtarget->hasNEON() &&
19441 !FuncAttributes.hasFnAttr(Attribute::NoImplicitFloat)) {
19442 unsigned Fast;
19443 if (Op.size() >= 16 &&
19444 (Op.isAligned(Align(16)) ||
19445 (allowsMisalignedMemoryAccesses(MVT::v2f64, 0, Align(1),
19447 Fast))) {
19448 return MVT::v2f64;
19449 } else if (Op.size() >= 8 &&
19450 (Op.isAligned(Align(8)) ||
19452 MVT::f64, 0, Align(1), MachineMemOperand::MONone, &Fast) &&
19453 Fast))) {
19454 return MVT::f64;
19455 }
19456 }
19457
19458 // Let the target-independent logic figure it out.
19459 return MVT::Other;
19460}
19461
19462// 64-bit integers are split into their high and low parts and held in two
19463// different registers, so the trunc is free since the low register can just
19464// be used.
19465bool ARMTargetLowering::isTruncateFree(Type *SrcTy, Type *DstTy) const {
19466 if (!SrcTy->isIntegerTy() || !DstTy->isIntegerTy())
19467 return false;
19468 unsigned SrcBits = SrcTy->getPrimitiveSizeInBits();
19469 unsigned DestBits = DstTy->getPrimitiveSizeInBits();
19470 return (SrcBits == 64 && DestBits == 32);
19471}
19472
19474 if (SrcVT.isVector() || DstVT.isVector() || !SrcVT.isInteger() ||
19475 !DstVT.isInteger())
19476 return false;
19477 unsigned SrcBits = SrcVT.getSizeInBits();
19478 unsigned DestBits = DstVT.getSizeInBits();
19479 return (SrcBits == 64 && DestBits == 32);
19480}
19481
19483 if (Val.getOpcode() != ISD::LOAD)
19484 return false;
19485
19486 EVT VT1 = Val.getValueType();
19487 if (!VT1.isSimple() || !VT1.isInteger() ||
19488 !VT2.isSimple() || !VT2.isInteger())
19489 return false;
19490
19491 switch (VT1.getSimpleVT().SimpleTy) {
19492 default: break;
19493 case MVT::i1:
19494 case MVT::i8:
19495 case MVT::i16:
19496 // 8-bit and 16-bit loads implicitly zero-extend to 32-bits.
19497 return true;
19498 }
19499
19500 return false;
19501}
19502
19504 if (!VT.isSimple())
19505 return false;
19506
19507 // There are quite a few FP16 instructions (e.g. VNMLA, VNMLS, etc.) that
19508 // negate values directly (fneg is free). So, we don't want to let the DAG
19509 // combiner rewrite fneg into xors and some other instructions. For f16 and
19510 // FullFP16 argument passing, some bitcast nodes may be introduced,
19511 // triggering this DAG combine rewrite, so we are avoiding that with this.
19512 switch (VT.getSimpleVT().SimpleTy) {
19513 default: break;
19514 case MVT::f16:
19515 return Subtarget->hasFullFP16();
19516 }
19517
19518 return false;
19519}
19520
19522 if (!Subtarget->hasMVEIntegerOps())
19523 return nullptr;
19524 Type *SVIType = SVI->getType();
19525 Type *ScalarType = SVIType->getScalarType();
19526
19527 if (ScalarType->isFloatTy())
19528 return Type::getInt32Ty(SVIType->getContext());
19529 if (ScalarType->isHalfTy())
19530 return Type::getInt16Ty(SVIType->getContext());
19531 return nullptr;
19532}
19533
19535 EVT VT = ExtVal.getValueType();
19536
19537 if (!isTypeLegal(VT))
19538 return false;
19539
19540 if (auto *Ld = dyn_cast<MaskedLoadSDNode>(ExtVal.getOperand(0))) {
19541 if (Ld->isExpandingLoad())
19542 return false;
19543 }
19544
19545 if (Subtarget->hasMVEIntegerOps())
19546 return true;
19547
19548 // Don't create a loadext if we can fold the extension into a wide/long
19549 // instruction.
19550 // If there's more than one user instruction, the loadext is desirable no
19551 // matter what. There can be two uses by the same instruction.
19552 if (ExtVal->use_empty() ||
19553 !ExtVal->user_begin()->isOnlyUserOf(ExtVal.getNode()))
19554 return true;
19555
19556 SDNode *U = *ExtVal->user_begin();
19557 if ((U->getOpcode() == ISD::ADD || U->getOpcode() == ISD::SUB ||
19558 U->getOpcode() == ISD::SHL || U->getOpcode() == ARMISD::VSHLIMM))
19559 return false;
19560
19561 return true;
19562}
19563
19565 if (!Ty1->isIntegerTy() || !Ty2->isIntegerTy())
19566 return false;
19567
19568 if (!isTypeLegal(EVT::getEVT(Ty1)))
19569 return false;
19570
19571 assert(Ty1->getPrimitiveSizeInBits() <= 64 && "i128 is probably not a noop");
19572
19573 // Assuming the caller doesn't have a zeroext or signext return parameter,
19574 // truncation all the way down to i1 is valid.
19575 return true;
19576}
19577
19578/// isFMAFasterThanFMulAndFAdd - Return true if an FMA operation is faster
19579/// than a pair of fmul and fadd instructions. fmuladd intrinsics will be
19580/// expanded to FMAs when this method returns true, otherwise fmuladd is
19581/// expanded to fmul + fadd.
19582///
19583/// ARM supports both fused and unfused multiply-add operations; we already
19584/// lower a pair of fmul and fadd to the latter so it's not clear that there
19585/// would be a gain or that the gain would be worthwhile enough to risk
19586/// correctness bugs.
19587///
19588/// For MVE, we set this to true as it helps simplify the need for some
19589/// patterns (and we don't have the non-fused floating point instruction).
19590bool ARMTargetLowering::isFMAFasterThanFMulAndFAdd(const MachineFunction &MF,
19591 EVT VT) const {
19592 if (Subtarget->useSoftFloat())
19593 return false;
19594
19595 if (!VT.isSimple())
19596 return false;
19597
19598 switch (VT.getSimpleVT().SimpleTy) {
19599 case MVT::v4f32:
19600 case MVT::v8f16:
19601 return Subtarget->hasMVEFloatOps();
19602 case MVT::f16:
19603 return Subtarget->useFPVFMx16();
19604 case MVT::f32:
19605 return Subtarget->useFPVFMx();
19606 case MVT::f64:
19607 return Subtarget->useFPVFMx64();
19608 default:
19609 break;
19610 }
19611
19612 return false;
19613}
19614
19615static bool isLegalT1AddressImmediate(int64_t V, EVT VT) {
19616 if (V < 0)
19617 return false;
19618
19619 unsigned Scale = 1;
19620 switch (VT.getSimpleVT().SimpleTy) {
19621 case MVT::i1:
19622 case MVT::i8:
19623 // Scale == 1;
19624 break;
19625 case MVT::i16:
19626 // Scale == 2;
19627 Scale = 2;
19628 break;
19629 default:
19630 // On thumb1 we load most things (i32, i64, floats, etc) with a LDR
19631 // Scale == 4;
19632 Scale = 4;
19633 break;
19634 }
19635
19636 if ((V & (Scale - 1)) != 0)
19637 return false;
19638 return isUInt<5>(V / Scale);
19639}
19640
19641static bool isLegalT2AddressImmediate(int64_t V, EVT VT,
19642 const ARMSubtarget *Subtarget) {
19643 if (!VT.isInteger() && !VT.isFloatingPoint())
19644 return false;
19645 if (VT.isVector() && Subtarget->hasNEON())
19646 return false;
19647 if (VT.isVector() && VT.isFloatingPoint() && Subtarget->hasMVEIntegerOps() &&
19648 !Subtarget->hasMVEFloatOps())
19649 return false;
19650
19651 bool IsNeg = false;
19652 if (V < 0) {
19653 IsNeg = true;
19654 V = -V;
19655 }
19656
19657 unsigned NumBytes = std::max((unsigned)VT.getSizeInBits() / 8, 1U);
19658
19659 // MVE: size * imm7
19660 if (VT.isVector() && Subtarget->hasMVEIntegerOps()) {
19661 switch (VT.getSimpleVT().getVectorElementType().SimpleTy) {
19662 case MVT::i32:
19663 case MVT::f32:
19664 return isShiftedUInt<7,2>(V);
19665 case MVT::i16:
19666 case MVT::f16:
19667 return isShiftedUInt<7,1>(V);
19668 case MVT::i8:
19669 return isUInt<7>(V);
19670 default:
19671 return false;
19672 }
19673 }
19674
19675 // half VLDR: 2 * imm8
19676 if (VT.isFloatingPoint() && NumBytes == 2 && Subtarget->hasFPRegs16())
19677 return isShiftedUInt<8, 1>(V);
19678 // VLDR and LDRD: 4 * imm8
19679 if ((VT.isFloatingPoint() && Subtarget->hasVFP2Base()) || NumBytes == 8)
19680 return isShiftedUInt<8, 2>(V);
19681
19682 if (NumBytes == 1 || NumBytes == 2 || NumBytes == 4) {
19683 // + imm12 or - imm8
19684 if (IsNeg)
19685 return isUInt<8>(V);
19686 return isUInt<12>(V);
19687 }
19688
19689 return false;
19690}
19691
19692/// isLegalAddressImmediate - Return true if the integer value can be used
19693/// as the offset of the target addressing mode for load / store of the
19694/// given type.
19695static bool isLegalAddressImmediate(int64_t V, EVT VT,
19696 const ARMSubtarget *Subtarget) {
19697 if (V == 0)
19698 return true;
19699
19700 if (!VT.isSimple())
19701 return false;
19702
19703 if (Subtarget->isThumb1Only())
19704 return isLegalT1AddressImmediate(V, VT);
19705 else if (Subtarget->isThumb2())
19706 return isLegalT2AddressImmediate(V, VT, Subtarget);
19707
19708 // ARM mode.
19709 if (V < 0)
19710 V = - V;
19711 switch (VT.getSimpleVT().SimpleTy) {
19712 default: return false;
19713 case MVT::i1:
19714 case MVT::i8:
19715 case MVT::i32:
19716 // +- imm12
19717 return isUInt<12>(V);
19718 case MVT::i16:
19719 // +- imm8
19720 return isUInt<8>(V);
19721 case MVT::f32:
19722 case MVT::f64:
19723 if (!Subtarget->hasVFP2Base()) // FIXME: NEON?
19724 return false;
19725 return isShiftedUInt<8, 2>(V);
19726 }
19727}
19728
19730 EVT VT) const {
19731 int Scale = AM.Scale;
19732 if (Scale < 0)
19733 return false;
19734
19735 switch (VT.getSimpleVT().SimpleTy) {
19736 default: return false;
19737 case MVT::i1:
19738 case MVT::i8:
19739 case MVT::i16:
19740 case MVT::i32:
19741 if (Scale == 1)
19742 return true;
19743 // r + r << imm
19744 Scale = Scale & ~1;
19745 return Scale == 2 || Scale == 4 || Scale == 8;
19746 case MVT::i64:
19747 // FIXME: What are we trying to model here? ldrd doesn't have an r + r
19748 // version in Thumb mode.
19749 // r + r
19750 if (Scale == 1)
19751 return true;
19752 // r * 2 (this can be lowered to r + r).
19753 if (!AM.HasBaseReg && Scale == 2)
19754 return true;
19755 return false;
19756 case MVT::isVoid:
19757 // Note, we allow "void" uses (basically, uses that aren't loads or
19758 // stores), because arm allows folding a scale into many arithmetic
19759 // operations. This should be made more precise and revisited later.
19760
19761 // Allow r << imm, but the imm has to be a multiple of two.
19762 if (Scale & 1) return false;
19763 return isPowerOf2_32(Scale);
19764 }
19765}
19766
19768 EVT VT) const {
19769 const int Scale = AM.Scale;
19770
19771 // Negative scales are not supported in Thumb1.
19772 if (Scale < 0)
19773 return false;
19774
19775 // Thumb1 addressing modes do not support register scaling excepting the
19776 // following cases:
19777 // 1. Scale == 1 means no scaling.
19778 // 2. Scale == 2 this can be lowered to r + r if there is no base register.
19779 return (Scale == 1) || (!AM.HasBaseReg && Scale == 2);
19780}
19781
19782/// isLegalAddressingMode - Return true if the addressing mode represented
19783/// by AM is legal for this target, for a load/store of the specified type.
19785 const AddrMode &AM, Type *Ty,
19786 unsigned AS, Instruction *I) const {
19787 EVT VT = getValueType(DL, Ty, true);
19788 if (!isLegalAddressImmediate(AM.BaseOffs, VT, Subtarget))
19789 return false;
19790
19791 // Can never fold addr of global into load/store.
19792 if (AM.BaseGV)
19793 return false;
19794
19795 switch (AM.Scale) {
19796 case 0: // no scale reg, must be "r+i" or "r", or "i".
19797 break;
19798 default:
19799 // ARM doesn't support any R+R*scale+imm addr modes.
19800 if (AM.BaseOffs)
19801 return false;
19802
19803 if (!VT.isSimple())
19804 return false;
19805
19806 if (Subtarget->isThumb1Only())
19807 return isLegalT1ScaledAddressingMode(AM, VT);
19808
19809 if (Subtarget->isThumb2())
19810 return isLegalT2ScaledAddressingMode(AM, VT);
19811
19812 int Scale = AM.Scale;
19813 switch (VT.getSimpleVT().SimpleTy) {
19814 default: return false;
19815 case MVT::i1:
19816 case MVT::i8:
19817 case MVT::i32:
19818 if (Scale < 0) Scale = -Scale;
19819 if (Scale == 1)
19820 return true;
19821 // r + r << imm
19822 return isPowerOf2_32(Scale & ~1);
19823 case MVT::i16:
19824 case MVT::i64:
19825 // r +/- r
19826 if (Scale == 1 || (AM.HasBaseReg && Scale == -1))
19827 return true;
19828 // r * 2 (this can be lowered to r + r).
19829 if (!AM.HasBaseReg && Scale == 2)
19830 return true;
19831 return false;
19832
19833 case MVT::isVoid:
19834 // Note, we allow "void" uses (basically, uses that aren't loads or
19835 // stores), because arm allows folding a scale into many arithmetic
19836 // operations. This should be made more precise and revisited later.
19837
19838 // Allow r << imm, but the imm has to be a multiple of two.
19839 if (Scale & 1) return false;
19840 return isPowerOf2_32(Scale);
19841 }
19842 }
19843 return true;
19844}
19845
19846/// isLegalICmpImmediate - Return true if the specified immediate is legal
19847/// icmp immediate, that is the target has icmp instructions which can compare
19848/// a register against the immediate without having to materialize the
19849/// immediate into a register.
19851 // Thumb2 and ARM modes can use cmn for negative immediates.
19852 if (!Subtarget->isThumb())
19853 return ARM_AM::getSOImmVal((uint32_t)Imm) != -1 ||
19855 if (Subtarget->isThumb2())
19856 return ARM_AM::getT2SOImmVal((uint32_t)Imm) != -1 ||
19858 // Thumb1 doesn't have cmn, and only 8-bit immediates.
19859 return Imm >= 0 && Imm <= 255;
19860}
19861
19862/// isLegalAddImmediate - Return true if the specified immediate is a legal add
19863/// *or sub* immediate, that is the target has add or sub instructions which can
19864/// add a register with the immediate without having to materialize the
19865/// immediate into a register.
19867 // Same encoding for add/sub, just flip the sign.
19868 uint64_t AbsImm = AbsoluteValue(Imm);
19869 if (!Subtarget->isThumb())
19870 return ARM_AM::getSOImmVal(AbsImm) != -1;
19871 if (Subtarget->isThumb2())
19872 return ARM_AM::getT2SOImmVal(AbsImm) != -1;
19873 // Thumb1 only has 8-bit unsigned immediate.
19874 return AbsImm <= 255;
19875}
19876
19877// Return false to prevent folding
19878// (mul (add r, c0), c1) -> (add (mul r, c1), c0*c1) in DAGCombine,
19879// if the folding leads to worse code.
19881 SDValue ConstNode) const {
19882 // Let the DAGCombiner decide for vector types and large types.
19883 const EVT VT = AddNode.getValueType();
19884 if (VT.isVector() || VT.getScalarSizeInBits() > 32)
19885 return true;
19886
19887 // It is worse if c0 is legal add immediate, while c1*c0 is not
19888 // and has to be composed by at least two instructions.
19889 const ConstantSDNode *C0Node = cast<ConstantSDNode>(AddNode.getOperand(1));
19890 const ConstantSDNode *C1Node = cast<ConstantSDNode>(ConstNode);
19891 const int64_t C0 = C0Node->getSExtValue();
19892 APInt CA = C0Node->getAPIntValue() * C1Node->getAPIntValue();
19894 return true;
19895 if (ConstantMaterializationCost((unsigned)CA.getZExtValue(), Subtarget) > 1)
19896 return false;
19897
19898 // Default to true and let the DAGCombiner decide.
19899 return true;
19900}
19901
19903 bool isSEXTLoad, SDValue &Base,
19904 SDValue &Offset, bool &isInc,
19905 SelectionDAG &DAG) {
19906 if (Ptr->getOpcode() != ISD::ADD && Ptr->getOpcode() != ISD::SUB)
19907 return false;
19908
19909 if (VT == MVT::i16 || ((VT == MVT::i8 || VT == MVT::i1) && isSEXTLoad)) {
19910 // AddressingMode 3
19911 Base = Ptr->getOperand(0);
19913 int RHSC = (int)RHS->getZExtValue();
19914 if (RHSC < 0 && RHSC > -256) {
19915 assert(Ptr->getOpcode() == ISD::ADD);
19916 isInc = false;
19917 Offset = DAG.getConstant(-RHSC, SDLoc(Ptr), RHS->getValueType(0));
19918 return true;
19919 }
19920 }
19921 isInc = (Ptr->getOpcode() == ISD::ADD);
19922 Offset = Ptr->getOperand(1);
19923 return true;
19924 } else if (VT == MVT::i32 || VT == MVT::i8 || VT == MVT::i1) {
19925 // AddressingMode 2
19927 int RHSC = (int)RHS->getZExtValue();
19928 if (RHSC < 0 && RHSC > -0x1000) {
19929 assert(Ptr->getOpcode() == ISD::ADD);
19930 isInc = false;
19931 Offset = DAG.getConstant(-RHSC, SDLoc(Ptr), RHS->getValueType(0));
19932 Base = Ptr->getOperand(0);
19933 return true;
19934 }
19935 }
19936
19937 if (Ptr->getOpcode() == ISD::ADD) {
19938 isInc = true;
19939 ARM_AM::ShiftOpc ShOpcVal=
19941 if (ShOpcVal != ARM_AM::no_shift) {
19942 Base = Ptr->getOperand(1);
19943 Offset = Ptr->getOperand(0);
19944 } else {
19945 Base = Ptr->getOperand(0);
19946 Offset = Ptr->getOperand(1);
19947 }
19948 return true;
19949 }
19950
19951 isInc = (Ptr->getOpcode() == ISD::ADD);
19952 Base = Ptr->getOperand(0);
19953 Offset = Ptr->getOperand(1);
19954 return true;
19955 }
19956
19957 // FIXME: Use VLDM / VSTM to emulate indexed FP load / store.
19958 return false;
19959}
19960
19962 bool isSEXTLoad, SDValue &Base,
19963 SDValue &Offset, bool &isInc,
19964 SelectionDAG &DAG) {
19965 if (Ptr->getOpcode() != ISD::ADD && Ptr->getOpcode() != ISD::SUB)
19966 return false;
19967
19968 Base = Ptr->getOperand(0);
19970 int RHSC = (int)RHS->getZExtValue();
19971 if (RHSC < 0 && RHSC > -0x100) { // 8 bits.
19972 assert(Ptr->getOpcode() == ISD::ADD);
19973 isInc = false;
19974 Offset = DAG.getConstant(-RHSC, SDLoc(Ptr), RHS->getValueType(0));
19975 return true;
19976 } else if (RHSC > 0 && RHSC < 0x100) { // 8 bit, no zero.
19977 isInc = Ptr->getOpcode() == ISD::ADD;
19978 Offset = DAG.getConstant(RHSC, SDLoc(Ptr), RHS->getValueType(0));
19979 return true;
19980 }
19981 }
19982
19983 return false;
19984}
19985
19986static bool getMVEIndexedAddressParts(SDNode *Ptr, EVT VT, Align Alignment,
19987 bool isSEXTLoad, bool IsMasked, bool isLE,
19989 bool &isInc, SelectionDAG &DAG) {
19990 if (Ptr->getOpcode() != ISD::ADD && Ptr->getOpcode() != ISD::SUB)
19991 return false;
19992 if (!isa<ConstantSDNode>(Ptr->getOperand(1)))
19993 return false;
19994
19995 // We allow LE non-masked loads to change the type (for example use a vldrb.8
19996 // as opposed to a vldrw.32). This can allow extra addressing modes or
19997 // alignments for what is otherwise an equivalent instruction.
19998 bool CanChangeType = isLE && !IsMasked;
19999
20001 int RHSC = (int)RHS->getZExtValue();
20002
20003 auto IsInRange = [&](int RHSC, int Limit, int Scale) {
20004 if (RHSC < 0 && RHSC > -Limit * Scale && RHSC % Scale == 0) {
20005 assert(Ptr->getOpcode() == ISD::ADD);
20006 isInc = false;
20007 Offset = DAG.getConstant(-RHSC, SDLoc(Ptr), RHS->getValueType(0));
20008 return true;
20009 } else if (RHSC > 0 && RHSC < Limit * Scale && RHSC % Scale == 0) {
20010 isInc = Ptr->getOpcode() == ISD::ADD;
20011 Offset = DAG.getConstant(RHSC, SDLoc(Ptr), RHS->getValueType(0));
20012 return true;
20013 }
20014 return false;
20015 };
20016
20017 // Try to find a matching instruction based on s/zext, Alignment, Offset and
20018 // (in BE/masked) type.
20019 Base = Ptr->getOperand(0);
20020 if (VT == MVT::v4i16) {
20021 if (Alignment >= 2 && IsInRange(RHSC, 0x80, 2))
20022 return true;
20023 } else if (VT == MVT::v4i8 || VT == MVT::v8i8) {
20024 if (IsInRange(RHSC, 0x80, 1))
20025 return true;
20026 } else if (Alignment >= 4 &&
20027 (CanChangeType || VT == MVT::v4i32 || VT == MVT::v4f32) &&
20028 IsInRange(RHSC, 0x80, 4))
20029 return true;
20030 else if (Alignment >= 2 &&
20031 (CanChangeType || VT == MVT::v8i16 || VT == MVT::v8f16) &&
20032 IsInRange(RHSC, 0x80, 2))
20033 return true;
20034 else if ((CanChangeType || VT == MVT::v16i8) && IsInRange(RHSC, 0x80, 1))
20035 return true;
20036 return false;
20037}
20038
20039/// getPreIndexedAddressParts - returns true by value, base pointer and
20040/// offset pointer and addressing mode by reference if the node's address
20041/// can be legally represented as pre-indexed load / store address.
20042bool
20044 SDValue &Offset,
20046 SelectionDAG &DAG) const {
20047 if (Subtarget->isThumb1Only())
20048 return false;
20049
20050 EVT VT;
20051 SDValue Ptr;
20052 Align Alignment;
20053 unsigned AS = 0;
20054 bool isSEXTLoad = false;
20055 bool IsMasked = false;
20056 if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N)) {
20057 Ptr = LD->getBasePtr();
20058 VT = LD->getMemoryVT();
20059 Alignment = LD->getAlign();
20060 AS = LD->getAddressSpace();
20061 isSEXTLoad = LD->getExtensionType() == ISD::SEXTLOAD;
20062 } else if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N)) {
20063 Ptr = ST->getBasePtr();
20064 VT = ST->getMemoryVT();
20065 Alignment = ST->getAlign();
20066 AS = ST->getAddressSpace();
20067 } else if (MaskedLoadSDNode *LD = dyn_cast<MaskedLoadSDNode>(N)) {
20068 Ptr = LD->getBasePtr();
20069 VT = LD->getMemoryVT();
20070 Alignment = LD->getAlign();
20071 AS = LD->getAddressSpace();
20072 isSEXTLoad = LD->getExtensionType() == ISD::SEXTLOAD;
20073 IsMasked = true;
20075 Ptr = ST->getBasePtr();
20076 VT = ST->getMemoryVT();
20077 Alignment = ST->getAlign();
20078 AS = ST->getAddressSpace();
20079 IsMasked = true;
20080 } else
20081 return false;
20082
20083 unsigned Fast = 0;
20084 if (!allowsMisalignedMemoryAccesses(VT, AS, Alignment,
20086 // Only generate post-increment or pre-increment forms when a real
20087 // hardware instruction exists for them. Do not emit postinc/preinc
20088 // if the operation will end up as a libcall.
20089 return false;
20090 }
20091
20092 bool isInc;
20093 bool isLegal = false;
20094 if (VT.isVector())
20095 isLegal = Subtarget->hasMVEIntegerOps() &&
20097 Ptr.getNode(), VT, Alignment, isSEXTLoad, IsMasked,
20098 Subtarget->isLittle(), Base, Offset, isInc, DAG);
20099 else {
20100 if (Subtarget->isThumb2())
20101 isLegal = getT2IndexedAddressParts(Ptr.getNode(), VT, isSEXTLoad, Base,
20102 Offset, isInc, DAG);
20103 else
20104 isLegal = getARMIndexedAddressParts(Ptr.getNode(), VT, isSEXTLoad, Base,
20105 Offset, isInc, DAG);
20106 }
20107 if (!isLegal)
20108 return false;
20109
20110 AM = isInc ? ISD::PRE_INC : ISD::PRE_DEC;
20111 return true;
20112}
20113
20114/// getPostIndexedAddressParts - returns true by value, base pointer and
20115/// offset pointer and addressing mode by reference if this node can be
20116/// combined with a load / store to form a post-indexed load / store.
20118 SDValue &Base,
20119 SDValue &Offset,
20121 SelectionDAG &DAG) const {
20122 EVT VT;
20123 SDValue Ptr;
20124 Align Alignment;
20125 bool isSEXTLoad = false, isNonExt;
20126 bool IsMasked = false;
20127 if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N)) {
20128 VT = LD->getMemoryVT();
20129 Ptr = LD->getBasePtr();
20130 Alignment = LD->getAlign();
20131 isSEXTLoad = LD->getExtensionType() == ISD::SEXTLOAD;
20132 isNonExt = LD->getExtensionType() == ISD::NON_EXTLOAD;
20133 } else if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N)) {
20134 VT = ST->getMemoryVT();
20135 Ptr = ST->getBasePtr();
20136 Alignment = ST->getAlign();
20137 isNonExt = !ST->isTruncatingStore();
20138 } else if (MaskedLoadSDNode *LD = dyn_cast<MaskedLoadSDNode>(N)) {
20139 VT = LD->getMemoryVT();
20140 Ptr = LD->getBasePtr();
20141 Alignment = LD->getAlign();
20142 isSEXTLoad = LD->getExtensionType() == ISD::SEXTLOAD;
20143 isNonExt = LD->getExtensionType() == ISD::NON_EXTLOAD;
20144 IsMasked = true;
20146 VT = ST->getMemoryVT();
20147 Ptr = ST->getBasePtr();
20148 Alignment = ST->getAlign();
20149 isNonExt = !ST->isTruncatingStore();
20150 IsMasked = true;
20151 } else
20152 return false;
20153
20154 if (Subtarget->isThumb1Only()) {
20155 // Thumb-1 can do a limited post-inc load or store as an updating LDM. It
20156 // must be non-extending/truncating, i32, with an offset of 4.
20157 assert(Op->getValueType(0) == MVT::i32 && "Non-i32 post-inc op?!");
20158 if (Op->getOpcode() != ISD::ADD || !isNonExt)
20159 return false;
20160 auto *RHS = dyn_cast<ConstantSDNode>(Op->getOperand(1));
20161 if (!RHS || RHS->getZExtValue() != 4)
20162 return false;
20163 if (Alignment < Align(4))
20164 return false;
20165
20166 Offset = Op->getOperand(1);
20167 Base = Op->getOperand(0);
20168 AM = ISD::POST_INC;
20169 return true;
20170 }
20171
20172 bool isInc;
20173 bool isLegal = false;
20174 if (VT.isVector())
20175 isLegal = Subtarget->hasMVEIntegerOps() &&
20176 getMVEIndexedAddressParts(Op, VT, Alignment, isSEXTLoad, IsMasked,
20177 Subtarget->isLittle(), Base, Offset,
20178 isInc, DAG);
20179 else {
20180 if (Subtarget->isThumb2())
20181 isLegal = getT2IndexedAddressParts(Op, VT, isSEXTLoad, Base, Offset,
20182 isInc, DAG);
20183 else
20184 isLegal = getARMIndexedAddressParts(Op, VT, isSEXTLoad, Base, Offset,
20185 isInc, DAG);
20186 }
20187 if (!isLegal)
20188 return false;
20189
20190 if (Ptr != Base) {
20191 // Swap base ptr and offset to catch more post-index load / store when
20192 // it's legal. In Thumb2 mode, offset must be an immediate.
20193 if (Ptr == Offset && Op->getOpcode() == ISD::ADD &&
20194 !Subtarget->isThumb2())
20196
20197 // Post-indexed load / store update the base pointer.
20198 if (Ptr != Base)
20199 return false;
20200 }
20201
20202 AM = isInc ? ISD::POST_INC : ISD::POST_DEC;
20203 return true;
20204}
20205
20208 const APInt &DemandedElts,
20209 const SelectionDAG &DAG,
20210 unsigned Depth) const {
20211 unsigned BitWidth = Known.getBitWidth();
20212 Known.resetAll();
20213 switch (Op.getOpcode()) {
20214 default: break;
20215 case ARMISD::ADDC:
20216 case ARMISD::ADDE:
20217 case ARMISD::SUBC:
20218 case ARMISD::SUBE:
20219 // Special cases when we convert a carry to a boolean.
20220 if (Op.getResNo() == 0) {
20221 SDValue LHS = Op.getOperand(0);
20222 SDValue RHS = Op.getOperand(1);
20223 // (ADDE 0, 0, C) will give us a single bit.
20224 if (Op->getOpcode() == ARMISD::ADDE && isNullConstant(LHS) &&
20225 isNullConstant(RHS)) {
20227 return;
20228 }
20229 }
20230 break;
20231 case ARMISD::CMOV: {
20232 // Bits are known zero/one if known on the LHS and RHS.
20233 Known = DAG.computeKnownBits(Op.getOperand(0), Depth+1);
20234 if (Known.isUnknown())
20235 return;
20236
20237 KnownBits KnownRHS = DAG.computeKnownBits(Op.getOperand(1), Depth+1);
20238 Known = Known.intersectWith(KnownRHS);
20239 return;
20240 }
20242 Intrinsic::ID IntID =
20243 static_cast<Intrinsic::ID>(Op->getConstantOperandVal(1));
20244 switch (IntID) {
20245 default: return;
20246 case Intrinsic::arm_ldaex:
20247 case Intrinsic::arm_ldrex: {
20248 EVT VT = cast<MemIntrinsicSDNode>(Op)->getMemoryVT();
20249 unsigned MemBits = VT.getScalarSizeInBits();
20250 Known.Zero |= APInt::getHighBitsSet(BitWidth, BitWidth - MemBits);
20251 return;
20252 }
20253 }
20254 }
20255 case ARMISD::BFI: {
20256 // Conservatively, we can recurse down the first operand
20257 // and just mask out all affected bits.
20258 Known = DAG.computeKnownBits(Op.getOperand(0), Depth + 1);
20259
20260 // The operand to BFI is already a mask suitable for removing the bits it
20261 // sets.
20262 const APInt &Mask = Op.getConstantOperandAPInt(2);
20263 Known.Zero &= Mask;
20264 Known.One &= Mask;
20265 return;
20266 }
20267 case ARMISD::VGETLANEs:
20268 case ARMISD::VGETLANEu: {
20269 const SDValue &SrcSV = Op.getOperand(0);
20270 EVT VecVT = SrcSV.getValueType();
20271 assert(VecVT.isVector() && "VGETLANE expected a vector type");
20272 const unsigned NumSrcElts = VecVT.getVectorNumElements();
20273 ConstantSDNode *Pos = cast<ConstantSDNode>(Op.getOperand(1).getNode());
20274 assert(Pos->getAPIntValue().ult(NumSrcElts) &&
20275 "VGETLANE index out of bounds");
20276 unsigned Idx = Pos->getZExtValue();
20277 APInt DemandedElt = APInt::getOneBitSet(NumSrcElts, Idx);
20278 Known = DAG.computeKnownBits(SrcSV, DemandedElt, Depth + 1);
20279
20280 EVT VT = Op.getValueType();
20281 const unsigned DstSz = VT.getScalarSizeInBits();
20282 const unsigned SrcSz = VecVT.getVectorElementType().getSizeInBits();
20283 (void)SrcSz;
20284 assert(SrcSz == Known.getBitWidth());
20285 assert(DstSz > SrcSz);
20286 if (Op.getOpcode() == ARMISD::VGETLANEs)
20287 Known = Known.sext(DstSz);
20288 else {
20289 Known = Known.zext(DstSz);
20290 }
20291 assert(DstSz == Known.getBitWidth());
20292 break;
20293 }
20294 case ARMISD::VMOVrh: {
20295 KnownBits KnownOp = DAG.computeKnownBits(Op->getOperand(0), Depth + 1);
20296 assert(KnownOp.getBitWidth() == 16);
20297 Known = KnownOp.zext(32);
20298 break;
20299 }
20300 case ARMISD::CSINC:
20301 case ARMISD::CSINV:
20302 case ARMISD::CSNEG: {
20303 KnownBits KnownOp0 = DAG.computeKnownBits(Op->getOperand(0), Depth + 1);
20304 KnownBits KnownOp1 = DAG.computeKnownBits(Op->getOperand(1), Depth + 1);
20305
20306 // The result is either:
20307 // CSINC: KnownOp0 or KnownOp1 + 1
20308 // CSINV: KnownOp0 or ~KnownOp1
20309 // CSNEG: KnownOp0 or KnownOp1 * -1
20310 if (Op.getOpcode() == ARMISD::CSINC)
20311 KnownOp1 =
20312 KnownBits::add(KnownOp1, KnownBits::makeConstant(APInt(32, 1)));
20313 else if (Op.getOpcode() == ARMISD::CSINV)
20314 std::swap(KnownOp1.Zero, KnownOp1.One);
20315 else if (Op.getOpcode() == ARMISD::CSNEG)
20316 KnownOp1 = KnownBits::mul(KnownOp1,
20318
20319 Known = KnownOp0.intersectWith(KnownOp1);
20320 break;
20321 }
20322 case ARMISD::VORRIMM:
20323 case ARMISD::VBICIMM: {
20324 unsigned Encoded = Op.getConstantOperandVal(1);
20325 unsigned DecEltBits = 0;
20326 uint64_t DecodedVal = ARM_AM::decodeVMOVModImm(Encoded, DecEltBits);
20327
20328 unsigned EltBits = Op.getScalarValueSizeInBits();
20329 if (EltBits != DecEltBits) {
20330 // Be conservative: only update Known when EltBits == DecEltBits.
20331 // This is believed to always be true for VORRIMM/VBICIMM today, but if
20332 // that changes in the future, doing nothing here is safer than risking
20333 // subtle bugs.
20334 break;
20335 }
20336
20337 KnownBits KnownLHS = DAG.computeKnownBits(Op.getOperand(0), Depth + 1);
20338 bool IsVORR = Op.getOpcode() == ARMISD::VORRIMM;
20339 APInt Imm(DecEltBits, DecodedVal);
20340
20341 Known.One = IsVORR ? (KnownLHS.One | Imm) : (KnownLHS.One & ~Imm);
20342 Known.Zero = IsVORR ? (KnownLHS.Zero & ~Imm) : (KnownLHS.Zero | Imm);
20343 break;
20344 }
20345 }
20346}
20347
20348static bool isLegalLogicalImmediate(unsigned Imm,
20349 const ARMSubtarget *Subtarget) {
20350 if (!Subtarget->isThumb())
20351 return ARM_AM::getSOImmVal(Imm) != -1;
20352 if (Subtarget->isThumb2())
20353 return ARM_AM::getT2SOImmVal(Imm) != -1;
20354 // Thumb1 only has 8-bit unsigned immediate.
20355 return Imm <= 255;
20356}
20357
20358/// Refine i32 AND/OR/XOR with a constant RHS using demanded bits: replace the
20359/// immediate with an equivalent constant that ARM/Thumb can encode as a
20360/// logical immediate (or that selects better lowering), without changing the
20361/// computed result on those demanded bits.
20362static bool optimizeLogicalImm(SDValue Op, unsigned Imm,
20363 const APInt &DemandedBits,
20364 const ARMSubtarget *Subtarget,
20366
20367 if (Imm == 0 || Imm == ~0U)
20368 return false;
20369
20370 unsigned Opc = Op.getOpcode();
20371 unsigned Demanded = DemandedBits.getZExtValue();
20372 EVT VT = Op.getValueType();
20373
20374 unsigned ShrunkImm = Imm & Demanded;
20375 unsigned ExpandedImm = Imm | ~Demanded;
20376
20377 auto IsLegalImm = [ShrunkImm, ExpandedImm](unsigned CandidateImm) -> bool {
20378 return (ShrunkImm & CandidateImm) == ShrunkImm &&
20379 (~ExpandedImm & CandidateImm) == 0;
20380 };
20381 auto UseImm = [Imm, Opc, Op, VT, &TLO](unsigned NewImm) -> bool {
20382 if (NewImm == Imm)
20383 return true;
20384 SDLoc DL(Op);
20385 SDValue NewC = TLO.DAG.getConstant(NewImm, DL, VT);
20386 SDValue NewOp =
20387 TLO.DAG.getNode(Opc, DL, VT, Op.getOperand(0), NewC, Op->getFlags());
20388 return TLO.CombineTo(Op, NewOp);
20389 };
20390
20391 // Shrunk immediate is 0: AND becomes zero; OR/XOR with 0 leaves the other
20392 // operand (still valid on demanded bits).
20393 if (ShrunkImm == 0) {
20394 ++NumOptimizedImms;
20395 return UseImm(ShrunkImm);
20396 }
20397
20398 // If the immediate is all ones: for AND this removes the operation; for
20399 // OR/XOR it remains a transform valid on demanded bits. (Target-independent
20400 // shrink may not fold this, so keep it to avoid obscure combine loops.)
20401 if (ExpandedImm == ~0U) {
20402 ++NumOptimizedImms;
20403 return UseImm(ExpandedImm);
20404 }
20405
20406 // Thumb1: prefer 0xFF / 0xFFFF when they fit the demanded-bit envelope so
20407 // lowering can match uxtb / uxth (AND immediates only; OR/XOR do not use
20408 // that). Run this before strict ShrunkImm: a tight 8-bit ShrunkImm can be
20409 // legal while 0xFF still matches the envelope and yields better isel (uxtb).
20410 if (Opc == ISD::AND && Subtarget->hasV6Ops()) {
20411 if (IsLegalImm(0xFF)) {
20412 ++NumOptimizedImms;
20413 return UseImm(0xFF);
20414 }
20415
20416 if (IsLegalImm(0xFFFF)) {
20417 ++NumOptimizedImms;
20418 return UseImm(0xFFFF);
20419 }
20420 }
20421
20422 // Don't optimize if it is legal.
20423 if (isLegalLogicalImmediate(Imm, Subtarget))
20424 return false;
20425
20426 // FIXME: Check for BIC being legal causes infinite loop due to target
20427 // independent DAG combine undoing this.
20428
20429 // Prefer strict shrink when ShrunkImm encodes for this target, before
20430 // complement expansion.
20431 if (isLegalLogicalImmediate(ShrunkImm, Subtarget)) {
20432 ++NumOptimizedImms;
20433 return UseImm(ShrunkImm);
20434 }
20435
20436 // Complement expansion: if all undemanded bits are already one, ExpandedImm
20437 // is Imm with every non-demanded bit set. When (~ExpandedImm) < 256, the
20438 // complement fits in an 8-bit unsigned value, i.e. bits 8–31 of ExpandedImm
20439 // are all ones; only the low byte may differ from ~0. Use that expanded
20440 // constant so isel sees a mask shape that fits logical-immediate patterns.
20441 if ((~ExpandedImm) < 256) {
20442 ++NumOptimizedImms;
20443 return UseImm(ExpandedImm);
20444 }
20445
20446 // FIXME: The check for v6 is because this interferes with some ubfx
20447 // optimizations.
20448 if (Opc == ISD::AND && isLegalLogicalImmediate(~ExpandedImm, Subtarget) &&
20449 !Subtarget->hasV6Ops()) {
20450 ++NumOptimizedImms;
20451 return UseImm(ExpandedImm);
20452 }
20453
20454 // Potential improvements:
20455 //
20456 // We could try to recognize lsls+lsrs or lsrs+lsls pairs here.
20457 // We could try to prefer Thumb1 immediates which can be lowered to a
20458 // two-instruction sequence.
20459
20460 return false;
20461}
20462
20464 SDValue Op, const APInt &DemandedBits, const APInt &DemandedElts,
20465 TargetLoweringOpt &TLO) const {
20466 // Delay this optimization to as late as possible.
20467 if (!TLO.LegalOps)
20468 return false;
20469
20470 EVT VT = Op.getValueType();
20471
20472 // Ignore vectors.
20473 if (VT.isVector())
20474 return false;
20475
20476 unsigned Size = VT.getSizeInBits();
20477
20478 if (Size != 32)
20479 return false;
20480
20481 // Exit early if we demand all bits.
20482 if (DemandedBits.isAllOnes())
20483 return false;
20484
20485 switch (Op.getOpcode()) {
20486 default:
20487 return false;
20488 case ISD::AND:
20489 case ISD::OR:
20490 case ISD::XOR:
20491 break;
20492 }
20493 ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op.getOperand(1));
20494 if (!C)
20495 return false;
20496 unsigned Imm = C->getZExtValue();
20497 return optimizeLogicalImm(Op, Imm, DemandedBits, Subtarget, TLO);
20498}
20499
20501 SDValue Op, const APInt &OriginalDemandedBits,
20502 const APInt &OriginalDemandedElts, KnownBits &Known, TargetLoweringOpt &TLO,
20503 unsigned Depth) const {
20504 unsigned Opc = Op.getOpcode();
20505
20506 switch (Opc) {
20507 case ARMISD::ASRL:
20508 case ARMISD::LSRL: {
20509 // If this is result 0 and the other result is unused, see if the demand
20510 // bits allow us to shrink this long shift into a standard small shift in
20511 // the opposite direction.
20512 if (Op.getResNo() == 0 && !Op->hasAnyUseOfValue(1) &&
20513 isa<ConstantSDNode>(Op->getOperand(2))) {
20514 unsigned ShAmt = Op->getConstantOperandVal(2);
20515 if (ShAmt < 32 && OriginalDemandedBits.isSubsetOf(APInt::getAllOnes(32)
20516 << (32 - ShAmt)))
20517 return TLO.CombineTo(
20518 Op, TLO.DAG.getNode(
20519 ISD::SHL, SDLoc(Op), MVT::i32, Op.getOperand(1),
20520 TLO.DAG.getConstant(32 - ShAmt, SDLoc(Op), MVT::i32)));
20521 }
20522 break;
20523 }
20524 case ARMISD::VBICIMM: {
20525 SDValue Op0 = Op.getOperand(0);
20526 unsigned ModImm = Op.getConstantOperandVal(1);
20527 unsigned EltBits = 0;
20528 uint64_t Mask = ARM_AM::decodeVMOVModImm(ModImm, EltBits);
20529 if ((OriginalDemandedBits & Mask) == 0)
20530 return TLO.CombineTo(Op, Op0);
20531 }
20532 }
20533
20535 Op, OriginalDemandedBits, OriginalDemandedElts, Known, TLO, Depth);
20536}
20537
20538//===----------------------------------------------------------------------===//
20539// ARM Inline Assembly Support
20540//===----------------------------------------------------------------------===//
20541
20542const char *ARMTargetLowering::LowerXConstraint(EVT ConstraintVT) const {
20543 // At this point, we have to lower this constraint to something else, so we
20544 // lower it to an "r" or "w". However, by doing this we will force the result
20545 // to be in register, while the X constraint is much more permissive.
20546 //
20547 // Although we are correct (we are free to emit anything, without
20548 // constraints), we might break use cases that would expect us to be more
20549 // efficient and emit something else.
20550 if (!Subtarget->hasVFP2Base())
20551 return "r";
20552 if (ConstraintVT.isFloatingPoint())
20553 return "w";
20554 if (ConstraintVT.isVector() && Subtarget->hasNEON() &&
20555 (ConstraintVT.getSizeInBits() == 64 ||
20556 ConstraintVT.getSizeInBits() == 128))
20557 return "w";
20558
20559 return "r";
20560}
20561
20562/// getConstraintType - Given a constraint letter, return the type of
20563/// constraint it is for this target.
20566 unsigned S = Constraint.size();
20567 if (S == 1) {
20568 switch (Constraint[0]) {
20569 default: break;
20570 case 'l': return C_RegisterClass;
20571 case 'w': return C_RegisterClass;
20572 case 'h': return C_RegisterClass;
20573 case 'x': return C_RegisterClass;
20574 case 't': return C_RegisterClass;
20575 case 'j': return C_Immediate; // Constant for movw.
20576 // An address with a single base register. Due to the way we
20577 // currently handle addresses it is the same as an 'r' memory constraint.
20578 case 'Q': return C_Memory;
20579 }
20580 } else if (S == 2) {
20581 switch (Constraint[0]) {
20582 default: break;
20583 case 'T': return C_RegisterClass;
20584 // All 'U+' constraints are addresses.
20585 case 'U': return C_Memory;
20586 }
20587 }
20588 return TargetLowering::getConstraintType(Constraint);
20589}
20590
20591/// Examine constraint type and operand type and determine a weight value.
20592/// This object must already have been set up with the operand type
20593/// and the current alternative constraint selected.
20596 AsmOperandInfo &info, const char *constraint) const {
20598 Value *CallOperandVal = info.CallOperandVal;
20599 // If we don't have a value, we can't do a match,
20600 // but allow it at the lowest weight.
20601 if (!CallOperandVal)
20602 return CW_Default;
20603 Type *type = CallOperandVal->getType();
20604 // Look at the constraint type.
20605 switch (*constraint) {
20606 default:
20608 break;
20609 case 'l':
20610 if (type->isIntegerTy()) {
20611 if (Subtarget->isThumb())
20612 weight = CW_SpecificReg;
20613 else
20614 weight = CW_Register;
20615 }
20616 break;
20617 case 'w':
20618 if (type->isFloatingPointTy())
20619 weight = CW_Register;
20620 break;
20621 }
20622 return weight;
20623}
20624
20625static bool isIncompatibleReg(const MCPhysReg &PR, MVT VT) {
20626 if (PR == 0 || VT == MVT::Other)
20627 return false;
20628 if (ARM::SPRRegClass.contains(PR))
20629 return VT != MVT::f32 && VT != MVT::f16 && VT != MVT::i32;
20630 if (ARM::DPRRegClass.contains(PR))
20631 return VT != MVT::f64 && !VT.is64BitVector();
20632 return false;
20633}
20634
20635using RCPair = std::pair<unsigned, const TargetRegisterClass *>;
20636
20638 const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const {
20639 switch (Constraint.size()) {
20640 case 1:
20641 // GCC ARM Constraint Letters
20642 switch (Constraint[0]) {
20643 case 'l': // Low regs or general regs.
20644 if (Subtarget->isThumb())
20645 return RCPair(0U, &ARM::tGPRRegClass);
20646 return RCPair(0U, &ARM::GPRRegClass);
20647 case 'h': // High regs or no regs.
20648 if (Subtarget->isThumb())
20649 return RCPair(0U, &ARM::hGPRRegClass);
20650 break;
20651 case 'r':
20652 if (Subtarget->isThumb1Only())
20653 return RCPair(0U, &ARM::tGPRRegClass);
20654 return RCPair(0U, &ARM::GPRRegClass);
20655 case 'w':
20656 if (VT == MVT::Other)
20657 break;
20658 if (VT == MVT::f32 || VT == MVT::f16 || VT == MVT::bf16)
20659 return RCPair(0U, &ARM::SPRRegClass);
20660 if (VT.getSizeInBits() == 64)
20661 return RCPair(0U, &ARM::DPRRegClass);
20662 if (VT.getSizeInBits() == 128)
20663 return RCPair(0U, &ARM::QPRRegClass);
20664 break;
20665 case 'x':
20666 if (VT == MVT::Other)
20667 break;
20668 if (VT == MVT::f32 || VT == MVT::f16 || VT == MVT::bf16)
20669 return RCPair(0U, &ARM::SPR_8RegClass);
20670 if (VT.getSizeInBits() == 64)
20671 return RCPair(0U, &ARM::DPR_8RegClass);
20672 if (VT.getSizeInBits() == 128)
20673 return RCPair(0U, &ARM::QPR_8RegClass);
20674 break;
20675 case 't':
20676 if (VT == MVT::Other)
20677 break;
20678 if (VT == MVT::f32 || VT == MVT::i32 || VT == MVT::f16 || VT == MVT::bf16)
20679 return RCPair(0U, &ARM::SPRRegClass);
20680 if (VT.getSizeInBits() == 64)
20681 return RCPair(0U, &ARM::DPR_VFP2RegClass);
20682 if (VT.getSizeInBits() == 128)
20683 return RCPair(0U, &ARM::QPR_VFP2RegClass);
20684 break;
20685 }
20686 break;
20687
20688 case 2:
20689 if (Constraint[0] == 'T') {
20690 switch (Constraint[1]) {
20691 default:
20692 break;
20693 case 'e':
20694 return RCPair(0U, &ARM::tGPREvenRegClass);
20695 case 'o':
20696 return RCPair(0U, &ARM::tGPROddRegClass);
20697 }
20698 }
20699 break;
20700
20701 default:
20702 break;
20703 }
20704
20705 if (StringRef("{cc}").equals_insensitive(Constraint))
20706 return std::make_pair(unsigned(ARM::CPSR), &ARM::CCRRegClass);
20707
20708 // r14 is an alias of lr.
20709 if (StringRef("{r14}").equals_insensitive(Constraint))
20710 return std::make_pair(unsigned(ARM::LR), getRegClassFor(MVT::i32));
20711
20712 auto RCP = TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT);
20713 if (isIncompatibleReg(RCP.first, VT))
20714 return {0, nullptr};
20715 return RCP;
20716}
20717
20718/// LowerAsmOperandForConstraint - Lower the specified operand into the Ops
20719/// vector. If it is invalid, don't add anything to Ops.
20721 StringRef Constraint,
20722 std::vector<SDValue> &Ops,
20723 SelectionDAG &DAG) const {
20724 SDValue Result;
20725
20726 // Currently only support length 1 constraints.
20727 if (Constraint.size() != 1)
20728 return;
20729
20730 char ConstraintLetter = Constraint[0];
20731 switch (ConstraintLetter) {
20732 default: break;
20733 case 'j':
20734 case 'I': case 'J': case 'K': case 'L':
20735 case 'M': case 'N': case 'O':
20737 if (!C)
20738 return;
20739
20740 int64_t CVal64 = C->getSExtValue();
20741 int CVal = (int) CVal64;
20742 // None of these constraints allow values larger than 32 bits. Check
20743 // that the value fits in an int.
20744 if (CVal != CVal64)
20745 return;
20746
20747 switch (ConstraintLetter) {
20748 case 'j':
20749 // Constant suitable for movw, must be between 0 and
20750 // 65535.
20751 if (Subtarget->hasV6T2Ops() || (Subtarget->hasV8MBaselineOps()))
20752 if (CVal >= 0 && CVal <= 65535)
20753 break;
20754 return;
20755 case 'I':
20756 if (Subtarget->isThumb1Only()) {
20757 // This must be a constant between 0 and 255, for ADD
20758 // immediates.
20759 if (CVal >= 0 && CVal <= 255)
20760 break;
20761 } else if (Subtarget->isThumb2()) {
20762 // A constant that can be used as an immediate value in a
20763 // data-processing instruction.
20764 if (ARM_AM::getT2SOImmVal(CVal) != -1)
20765 break;
20766 } else {
20767 // A constant that can be used as an immediate value in a
20768 // data-processing instruction.
20769 if (ARM_AM::getSOImmVal(CVal) != -1)
20770 break;
20771 }
20772 return;
20773
20774 case 'J':
20775 if (Subtarget->isThumb1Only()) {
20776 // This must be a constant between -255 and -1, for negated ADD
20777 // immediates. This can be used in GCC with an "n" modifier that
20778 // prints the negated value, for use with SUB instructions. It is
20779 // not useful otherwise but is implemented for compatibility.
20780 if (CVal >= -255 && CVal <= -1)
20781 break;
20782 } else {
20783 // This must be a constant between -4095 and 4095. This is suitable
20784 // for use as the immediate offset field in LDR and STR instructions
20785 // such as LDR r0,[r1,#offset].
20786 if (CVal >= -4095 && CVal <= 4095)
20787 break;
20788 }
20789 return;
20790
20791 case 'K':
20792 if (Subtarget->isThumb1Only()) {
20793 // A 32-bit value where only one byte has a nonzero value. Exclude
20794 // zero to match GCC. This constraint is used by GCC internally for
20795 // constants that can be loaded with a move/shift combination.
20796 // It is not useful otherwise but is implemented for compatibility.
20797 if (CVal != 0 && ARM_AM::isThumbImmShiftedVal(CVal))
20798 break;
20799 } else if (Subtarget->isThumb2()) {
20800 // A constant whose bitwise inverse can be used as an immediate
20801 // value in a data-processing instruction. This can be used in GCC
20802 // with a "B" modifier that prints the inverted value, for use with
20803 // BIC and MVN instructions. It is not useful otherwise but is
20804 // implemented for compatibility.
20805 if (ARM_AM::getT2SOImmVal(~CVal) != -1)
20806 break;
20807 } else {
20808 // A constant whose bitwise inverse can be used as an immediate
20809 // value in a data-processing instruction. This can be used in GCC
20810 // with a "B" modifier that prints the inverted value, for use with
20811 // BIC and MVN instructions. It is not useful otherwise but is
20812 // implemented for compatibility.
20813 if (ARM_AM::getSOImmVal(~CVal) != -1)
20814 break;
20815 }
20816 return;
20817
20818 case 'L':
20819 if (Subtarget->isThumb1Only()) {
20820 // This must be a constant between -7 and 7,
20821 // for 3-operand ADD/SUB immediate instructions.
20822 if (CVal >= -7 && CVal < 7)
20823 break;
20824 } else if (Subtarget->isThumb2()) {
20825 // A constant whose negation can be used as an immediate value in a
20826 // data-processing instruction. This can be used in GCC with an "n"
20827 // modifier that prints the negated value, for use with SUB
20828 // instructions. It is not useful otherwise but is implemented for
20829 // compatibility.
20830 if (ARM_AM::getT2SOImmVal(-CVal) != -1)
20831 break;
20832 } else {
20833 // A constant whose negation can be used as an immediate value in a
20834 // data-processing instruction. This can be used in GCC with an "n"
20835 // modifier that prints the negated value, for use with SUB
20836 // instructions. It is not useful otherwise but is implemented for
20837 // compatibility.
20838 if (ARM_AM::getSOImmVal(-CVal) != -1)
20839 break;
20840 }
20841 return;
20842
20843 case 'M':
20844 if (Subtarget->isThumb1Only()) {
20845 // This must be a multiple of 4 between 0 and 1020, for
20846 // ADD sp + immediate.
20847 if ((CVal >= 0 && CVal <= 1020) && ((CVal & 3) == 0))
20848 break;
20849 } else {
20850 // A power of two or a constant between 0 and 32. This is used in
20851 // GCC for the shift amount on shifted register operands, but it is
20852 // useful in general for any shift amounts.
20853 if ((CVal >= 0 && CVal <= 32) || ((CVal & (CVal - 1)) == 0))
20854 break;
20855 }
20856 return;
20857
20858 case 'N':
20859 if (Subtarget->isThumb1Only()) {
20860 // This must be a constant between 0 and 31, for shift amounts.
20861 if (CVal >= 0 && CVal <= 31)
20862 break;
20863 }
20864 return;
20865
20866 case 'O':
20867 if (Subtarget->isThumb1Only()) {
20868 // This must be a multiple of 4 between -508 and 508, for
20869 // ADD/SUB sp = sp + immediate.
20870 if ((CVal >= -508 && CVal <= 508) && ((CVal & 3) == 0))
20871 break;
20872 }
20873 return;
20874 }
20875 Result = DAG.getSignedTargetConstant(CVal, SDLoc(Op), Op.getValueType());
20876 break;
20877 }
20878
20879 if (Result.getNode()) {
20880 Ops.push_back(Result);
20881 return;
20882 }
20883 return TargetLowering::LowerAsmOperandForConstraint(Op, Constraint, Ops, DAG);
20884}
20885
20886static RTLIB::Libcall getDivRemLibcall(
20887 const SDNode *N, MVT::SimpleValueType SVT) {
20888 assert((N->getOpcode() == ISD::SDIVREM || N->getOpcode() == ISD::UDIVREM ||
20889 N->getOpcode() == ISD::SREM || N->getOpcode() == ISD::UREM) &&
20890 "Unhandled Opcode in getDivRemLibcall");
20891 bool isSigned = N->getOpcode() == ISD::SDIVREM ||
20892 N->getOpcode() == ISD::SREM;
20893 RTLIB::Libcall LC;
20894 switch (SVT) {
20895 default: llvm_unreachable("Unexpected request for libcall!");
20896 case MVT::i8: LC = isSigned ? RTLIB::SDIVREM_I8 : RTLIB::UDIVREM_I8; break;
20897 case MVT::i16: LC = isSigned ? RTLIB::SDIVREM_I16 : RTLIB::UDIVREM_I16; break;
20898 case MVT::i32: LC = isSigned ? RTLIB::SDIVREM_I32 : RTLIB::UDIVREM_I32; break;
20899 case MVT::i64: LC = isSigned ? RTLIB::SDIVREM_I64 : RTLIB::UDIVREM_I64; break;
20900 }
20901 return LC;
20902}
20903
20905 const SDNode *N, LLVMContext *Context, const ARMSubtarget *Subtarget) {
20906 assert((N->getOpcode() == ISD::SDIVREM || N->getOpcode() == ISD::UDIVREM ||
20907 N->getOpcode() == ISD::SREM || N->getOpcode() == ISD::UREM) &&
20908 "Unhandled Opcode in getDivRemArgList");
20909 bool isSigned = N->getOpcode() == ISD::SDIVREM ||
20910 N->getOpcode() == ISD::SREM;
20912 for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
20913 EVT ArgVT = N->getOperand(i).getValueType();
20914 Type *ArgTy = ArgVT.getTypeForEVT(*Context);
20915 TargetLowering::ArgListEntry Entry(N->getOperand(i), ArgTy);
20916 Entry.IsSExt = isSigned;
20917 Entry.IsZExt = !isSigned;
20918 Args.push_back(Entry);
20919 }
20920 if (Subtarget->getTargetTriple().isOSWindows() && Args.size() >= 2)
20921 std::swap(Args[0], Args[1]);
20922 return Args;
20923}
20924
20925SDValue ARMTargetLowering::LowerDivRem(SDValue Op, SelectionDAG &DAG) const {
20926 assert((Subtarget->isTargetAEABI() || Subtarget->isTargetAndroid() ||
20927 Subtarget->isTargetGNUAEABI() || Subtarget->isTargetMuslAEABI() ||
20928 Subtarget->isTargetFuchsia() || Subtarget->isTargetWindows()) &&
20929 "Register-based DivRem lowering only");
20930 unsigned Opcode = Op->getOpcode();
20931 assert((Opcode == ISD::SDIVREM || Opcode == ISD::UDIVREM) &&
20932 "Invalid opcode for Div/Rem lowering");
20933 bool isSigned = (Opcode == ISD::SDIVREM);
20934 EVT VT = Op->getValueType(0);
20935 SDLoc dl(Op);
20936
20937 if (VT == MVT::i64 && isa<ConstantSDNode>(Op.getOperand(1))) {
20939 if (expandDIVREMByConstant(Op.getNode(), Result, MVT::i32, DAG)) {
20940 SDValue Res0 =
20941 DAG.getNode(ISD::BUILD_PAIR, dl, VT, Result[0], Result[1]);
20942 SDValue Res1 =
20943 DAG.getNode(ISD::BUILD_PAIR, dl, VT, Result[2], Result[3]);
20944 return DAG.getNode(ISD::MERGE_VALUES, dl, Op->getVTList(),
20945 {Res0, Res1});
20946 }
20947 }
20948
20949 Type *Ty = VT.getTypeForEVT(*DAG.getContext());
20950
20951 // If the target has hardware divide, use divide + multiply + subtract:
20952 // div = a / b
20953 // rem = a - b * div
20954 // return {div, rem}
20955 // This should be lowered into UDIV/SDIV + MLS later on.
20956 bool hasDivide = Subtarget->isThumb() ? Subtarget->hasDivideInThumbMode()
20957 : Subtarget->hasDivideInARMMode();
20958 if (hasDivide && Op->getValueType(0).isSimple() &&
20959 Op->getSimpleValueType(0) == MVT::i32) {
20960 unsigned DivOpcode = isSigned ? ISD::SDIV : ISD::UDIV;
20961 const SDValue Dividend = Op->getOperand(0);
20962 const SDValue Divisor = Op->getOperand(1);
20963 SDValue Div = DAG.getNode(DivOpcode, dl, VT, Dividend, Divisor);
20964 SDValue Mul = DAG.getNode(ISD::MUL, dl, VT, Div, Divisor);
20965 SDValue Rem = DAG.getNode(ISD::SUB, dl, VT, Dividend, Mul);
20966
20967 SDValue Values[2] = {Div, Rem};
20968 return DAG.getNode(ISD::MERGE_VALUES, dl, DAG.getVTList(VT, VT), Values);
20969 }
20970
20971 RTLIB::Libcall LC = getDivRemLibcall(Op.getNode(),
20972 VT.getSimpleVT().SimpleTy);
20973 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
20974
20975 SDValue InChain = DAG.getEntryNode();
20976
20978 DAG.getContext(),
20979 Subtarget);
20980
20981 SDValue Callee =
20982 DAG.getExternalSymbol(LCImpl, getPointerTy(DAG.getDataLayout()));
20983
20984 Type *RetTy = StructType::get(Ty, Ty);
20985
20986 if (getTM().getTargetTriple().isOSWindows())
20987 InChain = WinDBZCheckDenominator(DAG, Op.getNode(), InChain);
20988
20989 TargetLowering::CallLoweringInfo CLI(DAG);
20990 CLI.setDebugLoc(dl)
20991 .setChain(InChain)
20992 .setCallee(DAG.getLibcalls().getLibcallImplCallingConv(LCImpl), RetTy,
20993 Callee, std::move(Args))
20994 .setInRegister()
20997
20998 std::pair<SDValue, SDValue> CallInfo = LowerCallTo(CLI);
20999 return CallInfo.first;
21000}
21001
21002// Lowers REM using divmod helpers
21003// see RTABI section 4.2/4.3
21004SDValue ARMTargetLowering::LowerREM(SDNode *N, SelectionDAG &DAG) const {
21005 EVT VT = N->getValueType(0);
21006
21007 if (VT == MVT::i64 && isa<ConstantSDNode>(N->getOperand(1))) {
21009 if (expandDIVREMByConstant(N, Result, MVT::i32, DAG))
21010 return DAG.getNode(ISD::BUILD_PAIR, SDLoc(N), N->getValueType(0),
21011 Result[0], Result[1]);
21012 }
21013
21014 // Build return types (div and rem)
21015 std::vector<Type*> RetTyParams;
21016 Type *RetTyElement;
21017
21018 switch (VT.getSimpleVT().SimpleTy) {
21019 default: llvm_unreachable("Unexpected request for libcall!");
21020 case MVT::i8: RetTyElement = Type::getInt8Ty(*DAG.getContext()); break;
21021 case MVT::i16: RetTyElement = Type::getInt16Ty(*DAG.getContext()); break;
21022 case MVT::i32: RetTyElement = Type::getInt32Ty(*DAG.getContext()); break;
21023 case MVT::i64: RetTyElement = Type::getInt64Ty(*DAG.getContext()); break;
21024 }
21025
21026 RetTyParams.push_back(RetTyElement);
21027 RetTyParams.push_back(RetTyElement);
21028 ArrayRef<Type*> ret = ArrayRef<Type*>(RetTyParams);
21029 Type *RetTy = StructType::get(*DAG.getContext(), ret);
21030
21031 RTLIB::Libcall LC = getDivRemLibcall(N, N->getValueType(0).getSimpleVT().
21032 SimpleTy);
21033 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
21034 SDValue InChain = DAG.getEntryNode();
21036 Subtarget);
21037 bool isSigned = N->getOpcode() == ISD::SREM;
21038
21039 SDValue Callee =
21040 DAG.getExternalSymbol(LCImpl, getPointerTy(DAG.getDataLayout()));
21041
21042 if (getTM().getTargetTriple().isOSWindows())
21043 InChain = WinDBZCheckDenominator(DAG, N, InChain);
21044
21045 // Lower call
21046 CallLoweringInfo CLI(DAG);
21047 CLI.setChain(InChain)
21048 .setCallee(DAG.getLibcalls().getLibcallImplCallingConv(LCImpl), RetTy,
21049 Callee, std::move(Args))
21052 .setDebugLoc(SDLoc(N));
21053 std::pair<SDValue, SDValue> CallResult = LowerCallTo(CLI);
21054
21055 // Return second (rem) result operand (first contains div)
21056 SDNode *ResNode = CallResult.first.getNode();
21057 assert(ResNode->getNumOperands() == 2 && "divmod should return two operands");
21058 return ResNode->getOperand(1);
21059}
21060
21061SDValue
21062ARMTargetLowering::LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const {
21063 assert(getTM().getTargetTriple().isOSWindows() &&
21064 "unsupported target platform");
21065 SDLoc DL(Op);
21066
21067 // Get the inputs.
21068 SDValue Chain = Op.getOperand(0);
21069 SDValue Size = Op.getOperand(1);
21070
21072 "no-stack-arg-probe")) {
21073 MaybeAlign Align =
21074 cast<ConstantSDNode>(Op.getOperand(2))->getMaybeAlignValue();
21075 SDValue SP = DAG.getCopyFromReg(Chain, DL, ARM::SP, MVT::i32);
21076 Chain = SP.getValue(1);
21077 SP = DAG.getNode(ISD::SUB, DL, MVT::i32, SP, Size);
21078 if (Align)
21079 SP = DAG.getNode(ISD::AND, DL, MVT::i32, SP.getValue(0),
21080 DAG.getSignedConstant(-Align->value(), DL, MVT::i32));
21081 Chain = DAG.getCopyToReg(Chain, DL, ARM::SP, SP);
21082 SDValue Ops[2] = { SP, Chain };
21083 return DAG.getMergeValues(Ops, DL);
21084 }
21085
21086 SDValue Words = DAG.getNode(ISD::SRL, DL, MVT::i32, Size,
21087 DAG.getConstant(2, DL, MVT::i32));
21088
21089 SDValue Glue;
21090 Chain = DAG.getCopyToReg(Chain, DL, ARM::R4, Words, Glue);
21091 Glue = Chain.getValue(1);
21092
21093 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
21094 Chain = DAG.getNode(ARMISD::WIN__CHKSTK, DL, NodeTys, Chain, Glue);
21095
21096 SDValue NewSP = DAG.getCopyFromReg(Chain, DL, ARM::SP, MVT::i32);
21097 Chain = NewSP.getValue(1);
21098
21099 SDValue Ops[2] = { NewSP, Chain };
21100 return DAG.getMergeValues(Ops, DL);
21101}
21102
21103SDValue ARMTargetLowering::LowerFP_EXTEND(SDValue Op, SelectionDAG &DAG) const {
21104 bool IsStrict = Op->isStrictFPOpcode();
21105 SDValue SrcVal = Op.getOperand(IsStrict ? 1 : 0);
21106 const unsigned DstSz = Op.getValueType().getSizeInBits();
21107 const unsigned SrcSz = SrcVal.getValueType().getSizeInBits();
21108 assert(DstSz > SrcSz && DstSz <= 64 && SrcSz >= 16 &&
21109 "Unexpected type for custom-lowering FP_EXTEND");
21110
21111 assert((!Subtarget->hasFP64() || !Subtarget->hasFPARMv8Base()) &&
21112 "With both FP DP and 16, any FP conversion is legal!");
21113
21114 assert(!(DstSz == 32 && Subtarget->hasFP16()) &&
21115 "With FP16, 16 to 32 conversion is legal!");
21116
21117 // Converting from 32 -> 64 is valid if we have FP64.
21118 if (SrcSz == 32 && DstSz == 64 && Subtarget->hasFP64()) {
21119 // FIXME: Remove this when we have strict fp instruction selection patterns
21120 if (IsStrict) {
21121 SDLoc Loc(Op);
21122 SDValue Result = DAG.getNode(ISD::FP_EXTEND,
21123 Loc, Op.getValueType(), SrcVal);
21124 return DAG.getMergeValues({Result, Op.getOperand(0)}, Loc);
21125 }
21126 return Op;
21127 }
21128
21129 // Either we are converting from 16 -> 64, without FP16 and/or
21130 // FP.double-precision or without Armv8-fp. So we must do it in two
21131 // steps.
21132 // Or we are converting from 32 -> 64 without fp.double-precision or 16 -> 32
21133 // without FP16. So we must do a function call.
21134 SDLoc Loc(Op);
21135 RTLIB::Libcall LC;
21136 MakeLibCallOptions CallOptions;
21137 SDValue Chain = IsStrict ? Op.getOperand(0) : SDValue();
21138 for (unsigned Sz = SrcSz; Sz <= 32 && Sz < DstSz; Sz *= 2) {
21139 bool Supported = (Sz == 16 ? Subtarget->hasFP16() : Subtarget->hasFP64());
21140 MVT SrcVT = (Sz == 16 ? MVT::f16 : MVT::f32);
21141 MVT DstVT = (Sz == 16 ? MVT::f32 : MVT::f64);
21142 if (Supported) {
21143 if (IsStrict) {
21144 SrcVal = DAG.getNode(ISD::STRICT_FP_EXTEND, Loc,
21145 {DstVT, MVT::Other}, {Chain, SrcVal});
21146 Chain = SrcVal.getValue(1);
21147 } else {
21148 SrcVal = DAG.getNode(ISD::FP_EXTEND, Loc, DstVT, SrcVal);
21149 }
21150 } else {
21151 LC = RTLIB::getFPEXT(SrcVT, DstVT);
21152 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
21153 "Unexpected type for custom-lowering FP_EXTEND");
21154 std::tie(SrcVal, Chain) = makeLibCall(DAG, LC, DstVT, SrcVal, CallOptions,
21155 Loc, Chain);
21156 }
21157 }
21158
21159 return IsStrict ? DAG.getMergeValues({SrcVal, Chain}, Loc) : SrcVal;
21160}
21161
21162SDValue ARMTargetLowering::LowerFP_ROUND(SDValue Op, SelectionDAG &DAG) const {
21163 bool IsStrict = Op->isStrictFPOpcode();
21164
21165 SDValue SrcVal = Op.getOperand(IsStrict ? 1 : 0);
21166 EVT SrcVT = SrcVal.getValueType();
21167 EVT DstVT = Op.getValueType();
21168
21169 if (DstVT == MVT::bf16) {
21170 if (Subtarget->hasBF16() && SrcVT == MVT::f32)
21171 return Op;
21172 return SDValue();
21173 }
21174
21175 const unsigned DstSz = Op.getValueType().getSizeInBits();
21176 const unsigned SrcSz = SrcVT.getSizeInBits();
21177 (void)DstSz;
21178 assert(DstSz < SrcSz && SrcSz <= 64 && DstSz >= 16 &&
21179 "Unexpected type for custom-lowering FP_ROUND");
21180
21181 assert((!Subtarget->hasFP64() || !Subtarget->hasFPARMv8Base()) &&
21182 "With both FP DP and 16, any FP conversion is legal!");
21183
21184 SDLoc Loc(Op);
21185
21186 // Instruction from 32 -> 16 if hasFP16 is valid
21187 if (SrcSz == 32 && Subtarget->hasFP16())
21188 return Op;
21189
21190 // Lib call from 32 -> 16 / 64 -> [32, 16]
21191 RTLIB::Libcall LC = RTLIB::getFPROUND(SrcVT, DstVT);
21192 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
21193 "Unexpected type for custom-lowering FP_ROUND");
21194 MakeLibCallOptions CallOptions;
21195 SDValue Chain = IsStrict ? Op.getOperand(0) : SDValue();
21196 SDValue Result;
21197 std::tie(Result, Chain) = makeLibCall(DAG, LC, DstVT, SrcVal, CallOptions,
21198 Loc, Chain);
21199 return IsStrict ? DAG.getMergeValues({Result, Chain}, Loc) : Result;
21200}
21201
21202bool
21204 // The ARM target isn't yet aware of offsets.
21205 return false;
21206}
21207
21209 if (v == 0xffffffff)
21210 return false;
21211
21212 // there can be 1's on either or both "outsides", all the "inside"
21213 // bits must be 0's
21214 return isShiftedMask_32(~v);
21215}
21216
21217/// isFPImmLegal - Returns true if the target can instruction select the
21218/// specified FP immediate natively. If false, the legalizer will
21219/// materialize the FP immediate as a load from a constant pool.
21221 bool ForCodeSize) const {
21222 if (!Subtarget->hasVFP3Base())
21223 return false;
21224 if (VT == MVT::f16 && Subtarget->hasFullFP16())
21225 return ARM_AM::getFP16Imm(Imm) != -1;
21226 if (VT == MVT::f32 && Subtarget->hasFullFP16() &&
21228 return true;
21229 if (VT == MVT::f32)
21230 return ARM_AM::getFP32Imm(Imm) != -1;
21231 if (VT == MVT::f64 && Subtarget->hasFP64())
21232 return ARM_AM::getFP64Imm(Imm) != -1;
21233 return false;
21234}
21235
21236/// getTgtMemIntrinsic - Represent NEON load and store intrinsics as
21237/// MemIntrinsicNodes. The associated MachineMemOperands record the alignment
21238/// specified in the intrinsic calls.
21241 MachineFunction &MF, unsigned Intrinsic) const {
21242 IntrinsicInfo Info;
21243 switch (Intrinsic) {
21244 case Intrinsic::arm_neon_vld1:
21245 case Intrinsic::arm_neon_vld2:
21246 case Intrinsic::arm_neon_vld3:
21247 case Intrinsic::arm_neon_vld4:
21248 case Intrinsic::arm_neon_vld2lane:
21249 case Intrinsic::arm_neon_vld3lane:
21250 case Intrinsic::arm_neon_vld4lane:
21251 case Intrinsic::arm_neon_vld2dup:
21252 case Intrinsic::arm_neon_vld3dup:
21253 case Intrinsic::arm_neon_vld4dup: {
21254 Info.opc = ISD::INTRINSIC_W_CHAIN;
21255 // Conservatively set memVT to the entire set of vectors loaded.
21256 auto &DL = I.getDataLayout();
21257 uint64_t NumElts = DL.getTypeSizeInBits(I.getType()) / 64;
21258 Info.memVT = EVT::getVectorVT(I.getType()->getContext(), MVT::i64, NumElts);
21259 Info.ptrVal = I.getArgOperand(0);
21260 Info.offset = 0;
21261 Value *AlignArg = I.getArgOperand(I.arg_size() - 1);
21262 Info.align = cast<ConstantInt>(AlignArg)->getMaybeAlignValue();
21263 // volatile loads with NEON intrinsics not supported
21264 Info.flags = MachineMemOperand::MOLoad;
21265 Infos.push_back(Info);
21266 return;
21267 }
21268 case Intrinsic::arm_neon_vld1x2:
21269 case Intrinsic::arm_neon_vld1x3:
21270 case Intrinsic::arm_neon_vld1x4: {
21271 Info.opc = ISD::INTRINSIC_W_CHAIN;
21272 // Conservatively set memVT to the entire set of vectors loaded.
21273 auto &DL = I.getDataLayout();
21274 uint64_t NumElts = DL.getTypeSizeInBits(I.getType()) / 64;
21275 Info.memVT = EVT::getVectorVT(I.getType()->getContext(), MVT::i64, NumElts);
21276 Info.ptrVal = I.getArgOperand(I.arg_size() - 1);
21277 Info.offset = 0;
21278 Info.align = I.getParamAlign(I.arg_size() - 1).valueOrOne();
21279 // volatile loads with NEON intrinsics not supported
21280 Info.flags = MachineMemOperand::MOLoad;
21281 Infos.push_back(Info);
21282 return;
21283 }
21284 case Intrinsic::arm_neon_vst1:
21285 case Intrinsic::arm_neon_vst2:
21286 case Intrinsic::arm_neon_vst3:
21287 case Intrinsic::arm_neon_vst4:
21288 case Intrinsic::arm_neon_vst2lane:
21289 case Intrinsic::arm_neon_vst3lane:
21290 case Intrinsic::arm_neon_vst4lane: {
21291 Info.opc = ISD::INTRINSIC_VOID;
21292 // Conservatively set memVT to the entire set of vectors stored.
21293 auto &DL = I.getDataLayout();
21294 unsigned NumElts = 0;
21295 for (unsigned ArgI = 1, ArgE = I.arg_size(); ArgI < ArgE; ++ArgI) {
21296 Type *ArgTy = I.getArgOperand(ArgI)->getType();
21297 if (!ArgTy->isVectorTy())
21298 break;
21299 NumElts += DL.getTypeSizeInBits(ArgTy) / 64;
21300 }
21301 Info.memVT = EVT::getVectorVT(I.getType()->getContext(), MVT::i64, NumElts);
21302 Info.ptrVal = I.getArgOperand(0);
21303 Info.offset = 0;
21304 Value *AlignArg = I.getArgOperand(I.arg_size() - 1);
21305 Info.align = cast<ConstantInt>(AlignArg)->getMaybeAlignValue();
21306 // volatile stores with NEON intrinsics not supported
21307 Info.flags = MachineMemOperand::MOStore;
21308 Infos.push_back(Info);
21309 return;
21310 }
21311 case Intrinsic::arm_neon_vst1x2:
21312 case Intrinsic::arm_neon_vst1x3:
21313 case Intrinsic::arm_neon_vst1x4: {
21314 Info.opc = ISD::INTRINSIC_VOID;
21315 // Conservatively set memVT to the entire set of vectors stored.
21316 auto &DL = I.getDataLayout();
21317 unsigned NumElts = 0;
21318 for (unsigned ArgI = 1, ArgE = I.arg_size(); ArgI < ArgE; ++ArgI) {
21319 Type *ArgTy = I.getArgOperand(ArgI)->getType();
21320 if (!ArgTy->isVectorTy())
21321 break;
21322 NumElts += DL.getTypeSizeInBits(ArgTy) / 64;
21323 }
21324 Info.memVT = EVT::getVectorVT(I.getType()->getContext(), MVT::i64, NumElts);
21325 Info.ptrVal = I.getArgOperand(0);
21326 Info.offset = 0;
21327 Info.align = I.getParamAlign(0).valueOrOne();
21328 // volatile stores with NEON intrinsics not supported
21329 Info.flags = MachineMemOperand::MOStore;
21330 Infos.push_back(Info);
21331 return;
21332 }
21333 case Intrinsic::arm_mve_vld2q:
21334 case Intrinsic::arm_mve_vld4q: {
21335 Info.opc = ISD::INTRINSIC_W_CHAIN;
21336 // Conservatively set memVT to the entire set of vectors loaded.
21337 Type *VecTy = cast<StructType>(I.getType())->getElementType(1);
21338 unsigned Factor = Intrinsic == Intrinsic::arm_mve_vld2q ? 2 : 4;
21339 Info.memVT = EVT::getVectorVT(VecTy->getContext(), MVT::i64, Factor * 2);
21340 Info.ptrVal = I.getArgOperand(0);
21341 Info.offset = 0;
21342 Info.align = Align(VecTy->getScalarSizeInBits() / 8);
21343 // volatile loads with MVE intrinsics not supported
21344 Info.flags = MachineMemOperand::MOLoad;
21345 Infos.push_back(Info);
21346 return;
21347 }
21348 case Intrinsic::arm_mve_vst2q:
21349 case Intrinsic::arm_mve_vst4q: {
21350 Info.opc = ISD::INTRINSIC_VOID;
21351 // Conservatively set memVT to the entire set of vectors stored.
21352 Type *VecTy = I.getArgOperand(1)->getType();
21353 unsigned Factor = Intrinsic == Intrinsic::arm_mve_vst2q ? 2 : 4;
21354 Info.memVT = EVT::getVectorVT(VecTy->getContext(), MVT::i64, Factor * 2);
21355 Info.ptrVal = I.getArgOperand(0);
21356 Info.offset = 0;
21357 Info.align = Align(VecTy->getScalarSizeInBits() / 8);
21358 // volatile stores with MVE intrinsics not supported
21359 Info.flags = MachineMemOperand::MOStore;
21360 Infos.push_back(Info);
21361 return;
21362 }
21363 case Intrinsic::arm_mve_vldr_gather_base:
21364 case Intrinsic::arm_mve_vldr_gather_base_predicated: {
21365 Info.opc = ISD::INTRINSIC_W_CHAIN;
21366 Info.ptrVal = nullptr;
21367 Info.memVT = MVT::getVT(I.getType());
21368 Info.align = Align(1);
21369 Info.flags |= MachineMemOperand::MOLoad;
21370 Infos.push_back(Info);
21371 return;
21372 }
21373 case Intrinsic::arm_mve_vldr_gather_base_wb:
21374 case Intrinsic::arm_mve_vldr_gather_base_wb_predicated: {
21375 Info.opc = ISD::INTRINSIC_W_CHAIN;
21376 Info.ptrVal = nullptr;
21377 Info.memVT = MVT::getVT(I.getType()->getContainedType(0));
21378 Info.align = Align(1);
21379 Info.flags |= MachineMemOperand::MOLoad;
21380 Infos.push_back(Info);
21381 return;
21382 }
21383 case Intrinsic::arm_mve_vldr_gather_offset:
21384 case Intrinsic::arm_mve_vldr_gather_offset_predicated: {
21385 Info.opc = ISD::INTRINSIC_W_CHAIN;
21386 Info.ptrVal = nullptr;
21387 MVT DataVT = MVT::getVT(I.getType());
21388 unsigned MemSize = cast<ConstantInt>(I.getArgOperand(2))->getZExtValue();
21389 Info.memVT = MVT::getVectorVT(MVT::getIntegerVT(MemSize),
21390 DataVT.getVectorNumElements());
21391 Info.align = Align(1);
21392 Info.flags |= MachineMemOperand::MOLoad;
21393 Infos.push_back(Info);
21394 return;
21395 }
21396 case Intrinsic::arm_mve_vstr_scatter_base:
21397 case Intrinsic::arm_mve_vstr_scatter_base_predicated: {
21398 Info.opc = ISD::INTRINSIC_VOID;
21399 Info.ptrVal = nullptr;
21400 Info.memVT = MVT::getVT(I.getArgOperand(2)->getType());
21401 Info.align = Align(1);
21402 Info.flags |= MachineMemOperand::MOStore;
21403 Infos.push_back(Info);
21404 return;
21405 }
21406 case Intrinsic::arm_mve_vstr_scatter_base_wb:
21407 case Intrinsic::arm_mve_vstr_scatter_base_wb_predicated: {
21408 Info.opc = ISD::INTRINSIC_W_CHAIN;
21409 Info.ptrVal = nullptr;
21410 Info.memVT = MVT::getVT(I.getArgOperand(2)->getType());
21411 Info.align = Align(1);
21412 Info.flags |= MachineMemOperand::MOStore;
21413 Infos.push_back(Info);
21414 return;
21415 }
21416 case Intrinsic::arm_mve_vstr_scatter_offset:
21417 case Intrinsic::arm_mve_vstr_scatter_offset_predicated: {
21418 Info.opc = ISD::INTRINSIC_VOID;
21419 Info.ptrVal = nullptr;
21420 MVT DataVT = MVT::getVT(I.getArgOperand(2)->getType());
21421 unsigned MemSize = cast<ConstantInt>(I.getArgOperand(3))->getZExtValue();
21422 Info.memVT = MVT::getVectorVT(MVT::getIntegerVT(MemSize),
21423 DataVT.getVectorNumElements());
21424 Info.align = Align(1);
21425 Info.flags |= MachineMemOperand::MOStore;
21426 Infos.push_back(Info);
21427 return;
21428 }
21429 case Intrinsic::arm_ldaex:
21430 case Intrinsic::arm_ldrex: {
21431 auto &DL = I.getDataLayout();
21432 Type *ValTy = I.getParamElementType(0);
21433 Info.opc = ISD::INTRINSIC_W_CHAIN;
21434 Info.memVT = MVT::getVT(ValTy);
21435 Info.ptrVal = I.getArgOperand(0);
21436 Info.offset = 0;
21437 Info.align = DL.getABITypeAlign(ValTy);
21439 Infos.push_back(Info);
21440 return;
21441 }
21442 case Intrinsic::arm_stlex:
21443 case Intrinsic::arm_strex: {
21444 auto &DL = I.getDataLayout();
21445 Type *ValTy = I.getParamElementType(1);
21446 Info.opc = ISD::INTRINSIC_W_CHAIN;
21447 Info.memVT = MVT::getVT(ValTy);
21448 Info.ptrVal = I.getArgOperand(1);
21449 Info.offset = 0;
21450 Info.align = DL.getABITypeAlign(ValTy);
21452 Infos.push_back(Info);
21453 return;
21454 }
21455 case Intrinsic::arm_stlexd:
21456 case Intrinsic::arm_strexd:
21457 Info.opc = ISD::INTRINSIC_W_CHAIN;
21458 Info.memVT = MVT::i64;
21459 Info.ptrVal = I.getArgOperand(2);
21460 Info.offset = 0;
21461 Info.align = Align(8);
21463 Infos.push_back(Info);
21464 return;
21465
21466 case Intrinsic::arm_ldaexd:
21467 case Intrinsic::arm_ldrexd:
21468 Info.opc = ISD::INTRINSIC_W_CHAIN;
21469 Info.memVT = MVT::i64;
21470 Info.ptrVal = I.getArgOperand(0);
21471 Info.offset = 0;
21472 Info.align = Align(8);
21474 Infos.push_back(Info);
21475 return;
21476
21477 default:
21478 break;
21479 }
21480}
21481
21482/// Returns true if it is beneficial to convert a load of a constant
21483/// to just the constant itself.
21485 Type *Ty) const {
21486 assert(Ty->isIntegerTy());
21487
21488 unsigned Bits = Ty->getPrimitiveSizeInBits();
21489 if (Bits == 0 || Bits > 32)
21490 return false;
21491 return true;
21492}
21493
21496 unsigned Index) const {
21499
21500 if (Index == 0 || Index == ResVT.getVectorNumElements())
21503}
21504
21506 ARM_MB::MemBOpt Domain) const {
21507 // First, if the target has no DMB, see what fallback we can use.
21508 if (!Subtarget->hasDataBarrier()) {
21509 // Some ARMv6 cpus can support data barriers with an mcr instruction.
21510 // Thumb1 and pre-v6 ARM mode use a libcall instead and should never get
21511 // here.
21512 if (Subtarget->hasV6Ops() && !Subtarget->isThumb()) {
21513 Value* args[6] = {Builder.getInt32(15), Builder.getInt32(0),
21514 Builder.getInt32(0), Builder.getInt32(7),
21515 Builder.getInt32(10), Builder.getInt32(5)};
21516 return Builder.CreateIntrinsicWithoutFolding(Intrinsic::arm_mcr, args);
21517 }
21518 // Instead of using barriers, atomic accesses on these subtargets use
21519 // libcalls.
21520 llvm_unreachable("makeDMB on a target so old that it has no barriers");
21521 } else {
21522 // Only a full system barrier exists in the M-class architectures.
21523 Domain = Subtarget->isMClass() ? ARM_MB::SY : Domain;
21524 Constant *CDomain = Builder.getInt32(Domain);
21525 return Builder.CreateIntrinsicWithoutFolding(Intrinsic::arm_dmb, CDomain);
21526 }
21527}
21528
21529// Based on http://www.cl.cam.ac.uk/~pes20/cpp/cpp0xmappings.html
21531 Instruction *Inst,
21532 AtomicOrdering Ord) const {
21533 switch (Ord) {
21536 llvm_unreachable("Invalid fence: unordered/non-atomic");
21539 return nullptr; // Nothing to do
21541 if (!Inst->hasAtomicStore())
21542 return nullptr; // Nothing to do
21543 [[fallthrough]];
21546 if (Subtarget->preferISHSTBarriers())
21547 return makeDMB(Builder, ARM_MB::ISHST);
21548 // FIXME: add a comment with a link to documentation justifying this.
21549 else
21550 return makeDMB(Builder, ARM_MB::ISH);
21551 }
21552 llvm_unreachable("Unknown fence ordering in emitLeadingFence");
21553}
21554
21556 Instruction *Inst,
21557 AtomicOrdering Ord) const {
21558 switch (Ord) {
21561 llvm_unreachable("Invalid fence: unordered/not-atomic");
21564 return nullptr; // Nothing to do
21568 return makeDMB(Builder, ARM_MB::ISH);
21569 }
21570 llvm_unreachable("Unknown fence ordering in emitTrailingFence");
21571}
21572
21573// Loads and stores less than 64-bits are already atomic; ones above that
21574// are doomed anyway, so defer to the default libcall and blame the OS when
21575// things go wrong. Cortex M doesn't have ldrexd/strexd though, so don't emit
21576// anything for those.
21579 bool has64BitAtomicStore;
21580 if (Subtarget->isMClass())
21581 has64BitAtomicStore = false;
21582 else if (Subtarget->isThumb())
21583 has64BitAtomicStore = Subtarget->hasV7Ops();
21584 else
21585 has64BitAtomicStore = Subtarget->hasV6Ops();
21586
21587 unsigned Size = SI->getValueOperand()->getType()->getPrimitiveSizeInBits();
21588 return Size == 64 && has64BitAtomicStore ? AtomicExpansionKind::Expand
21590}
21591
21592// Loads and stores less than 64-bits are already atomic; ones above that
21593// are doomed anyway, so defer to the default libcall and blame the OS when
21594// things go wrong. Cortex M doesn't have ldrexd/strexd though, so don't emit
21595// anything for those.
21596// FIXME: ldrd and strd are atomic if the CPU has LPAE (e.g. A15 has that
21597// guarantee, see DDI0406C ARM architecture reference manual,
21598// sections A8.8.72-74 LDRD)
21601 bool has64BitAtomicLoad;
21602 if (Subtarget->isMClass())
21603 has64BitAtomicLoad = false;
21604 else if (Subtarget->isThumb())
21605 has64BitAtomicLoad = Subtarget->hasV7Ops();
21606 else
21607 has64BitAtomicLoad = Subtarget->hasV6Ops();
21608
21609 unsigned Size = LI->getType()->getPrimitiveSizeInBits();
21610 return (Size == 64 && has64BitAtomicLoad) ? AtomicExpansionKind::LLOnly
21612}
21613
21614// For the real atomic operations, we have ldrex/strex up to 32 bits,
21615// and up to 64 bits on the non-M profiles
21618 if (AI->isFloatingPointOperation())
21620
21621 unsigned Size = AI->getType()->getPrimitiveSizeInBits();
21622 bool hasAtomicRMW;
21623 if (Subtarget->isMClass())
21624 hasAtomicRMW = Subtarget->hasV8MBaselineOps();
21625 else if (Subtarget->isThumb())
21626 hasAtomicRMW = Subtarget->hasV7Ops();
21627 else
21628 hasAtomicRMW = Subtarget->hasV6Ops();
21629 if (Size <= (Subtarget->isMClass() ? 32U : 64U) && hasAtomicRMW) {
21630 // At -O0, fast-regalloc cannot cope with the live vregs necessary to
21631 // implement atomicrmw without spilling. If the target address is also on
21632 // the stack and close enough to the spill slot, this can lead to a
21633 // situation where the monitor always gets cleared and the atomic operation
21634 // can never succeed. So at -O0 lower this operation to a CAS loop.
21635 if (getTargetMachine().getOptLevel() == CodeGenOptLevel::None)
21638 }
21640}
21641
21642// Similar to shouldExpandAtomicRMWInIR, ldrex/strex can be used up to 32
21643// bits, and up to 64 bits on the non-M profiles.
21646 const AtomicCmpXchgInst *AI) const {
21647 // At -O0, fast-regalloc cannot cope with the live vregs necessary to
21648 // implement cmpxchg without spilling. If the address being exchanged is also
21649 // on the stack and close enough to the spill slot, this can lead to a
21650 // situation where the monitor always gets cleared and the atomic operation
21651 // can never succeed. So at -O0 we need a late-expanded pseudo-inst instead.
21652 unsigned Size = AI->getOperand(1)->getType()->getPrimitiveSizeInBits();
21653 bool HasAtomicCmpXchg;
21654 if (Subtarget->isMClass())
21655 HasAtomicCmpXchg = Subtarget->hasV8MBaselineOps();
21656 else if (Subtarget->isThumb())
21657 HasAtomicCmpXchg = Subtarget->hasV7Ops();
21658 else
21659 HasAtomicCmpXchg = Subtarget->hasV6Ops();
21660 if (getTargetMachine().getOptLevel() != CodeGenOptLevel::None &&
21661 HasAtomicCmpXchg && Size <= (Subtarget->isMClass() ? 32U : 64U))
21664}
21665
21667 const Instruction *I) const {
21668 return InsertFencesForAtomic;
21669}
21670
21672 // ROPI/RWPI are not supported currently.
21673 return !Subtarget->isROPI() && !Subtarget->isRWPI();
21674}
21675
21677 Module &M, const LibcallLoweringInfo &Libcalls) const {
21678 // MSVC CRT provides functionalities for stack protection.
21679 RTLIB::LibcallImpl SecurityCheckCookieLibcall =
21680 Libcalls.getLibcallImpl(RTLIB::SECURITY_CHECK_COOKIE);
21681
21682 RTLIB::LibcallImpl SecurityCookieVar =
21683 Libcalls.getLibcallImpl(RTLIB::STACK_CHECK_GUARD);
21684 if (SecurityCheckCookieLibcall != RTLIB::Unsupported &&
21685 SecurityCookieVar != RTLIB::Unsupported) {
21686 // MSVC CRT has a global variable holding security cookie.
21687 M.getOrInsertGlobal(getLibcallImplName(SecurityCookieVar),
21688 PointerType::getUnqual(M.getContext()));
21689
21690 // MSVC CRT has a function to validate security cookie.
21691 FunctionCallee SecurityCheckCookie =
21692 M.getOrInsertFunction(getLibcallImplName(SecurityCheckCookieLibcall),
21693 Type::getVoidTy(M.getContext()),
21694 PointerType::getUnqual(M.getContext()));
21695 if (Function *F = dyn_cast<Function>(SecurityCheckCookie.getCallee()))
21696 F->addParamAttr(0, Attribute::AttrKind::InReg);
21697 }
21698
21700}
21701
21703 unsigned &Cost) const {
21704 // If we do not have NEON, vector types are not natively supported.
21705 if (!Subtarget->hasNEON())
21706 return false;
21707
21708 // Floating point values and vector values map to the same register file.
21709 // Therefore, although we could do a store extract of a vector type, this is
21710 // better to leave at float as we have more freedom in the addressing mode for
21711 // those.
21712 if (VectorTy->isFPOrFPVectorTy())
21713 return false;
21714
21715 // If the index is unknown at compile time, this is very expensive to lower
21716 // and it is not possible to combine the store with the extract.
21717 if (!isa<ConstantInt>(Idx))
21718 return false;
21719
21720 assert(VectorTy->isVectorTy() && "VectorTy is not a vector type");
21721 unsigned BitWidth = VectorTy->getPrimitiveSizeInBits().getFixedValue();
21722 // We can do a store + vector extract on any vector that fits perfectly in a D
21723 // or Q register.
21724 if (BitWidth == 64 || BitWidth == 128) {
21725 Cost = 0;
21726 return true;
21727 }
21728 return false;
21729}
21730
21732 SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG,
21733 UndefPoisonKind Kind, bool ConsiderFlags, unsigned Depth) const {
21734 unsigned Opcode = Op.getOpcode();
21735 switch (Opcode) {
21736 case ARMISD::VORRIMM:
21737 case ARMISD::VBICIMM:
21738 return false;
21739 }
21741 Op, DemandedElts, DAG, Kind, ConsiderFlags, Depth);
21742}
21743
21745 return Subtarget->hasV5TOps() && !Subtarget->isThumb1Only();
21746}
21747
21749 return Subtarget->hasV5TOps() && !Subtarget->isThumb1Only();
21750}
21751
21753 const Instruction &AndI) const {
21754 if (!Subtarget->hasV7Ops())
21755 return false;
21756
21757 // Sink the `and` instruction only if the mask would fit into a modified
21758 // immediate operand.
21760 if (!Mask || Mask->getValue().getBitWidth() > 32u)
21761 return false;
21762 auto MaskVal = unsigned(Mask->getValue().getZExtValue());
21763 return (Subtarget->isThumb2() ? ARM_AM::getT2SOImmVal(MaskVal)
21764 : ARM_AM::getSOImmVal(MaskVal)) != -1;
21765}
21766
21769 SelectionDAG &DAG, SDNode *N, unsigned ExpansionFactor) const {
21770 if (Subtarget->hasMinSize() && !getTM().getTargetTriple().isOSWindows())
21773 ExpansionFactor);
21774}
21775
21777 Value *Addr,
21778 AtomicOrdering Ord) const {
21779 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
21780 bool IsAcquire = isAcquireOrStronger(Ord);
21781
21782 // Since i64 isn't legal and intrinsics don't get type-lowered, the ldrexd
21783 // intrinsic must return {i32, i32} and we have to recombine them into a
21784 // single i64 here.
21785 if (ValueTy->getPrimitiveSizeInBits() == 64) {
21787 IsAcquire ? Intrinsic::arm_ldaexd : Intrinsic::arm_ldrexd;
21788
21789 Value *LoHi =
21790 Builder.CreateIntrinsic(Int, Addr, /*FMFSource=*/nullptr, "lohi");
21791
21792 Value *Lo = Builder.CreateExtractValue(LoHi, 0, "lo");
21793 Value *Hi = Builder.CreateExtractValue(LoHi, 1, "hi");
21794 if (!Subtarget->isLittle())
21795 std::swap (Lo, Hi);
21796 Lo = Builder.CreateZExt(Lo, ValueTy, "lo64");
21797 Hi = Builder.CreateZExt(Hi, ValueTy, "hi64");
21798 return Builder.CreateOr(
21799 Lo, Builder.CreateShl(Hi, ConstantInt::get(ValueTy, 32)), "val64");
21800 }
21801
21802 Type *Tys[] = { Addr->getType() };
21803 Intrinsic::ID Int = IsAcquire ? Intrinsic::arm_ldaex : Intrinsic::arm_ldrex;
21804 CallInst *CI = Builder.CreateIntrinsicWithoutFolding(Int, Tys, Addr);
21805
21806 CI->addParamAttr(
21807 0, Attribute::get(M->getContext(), Attribute::ElementType, ValueTy));
21808 return Builder.CreateTruncOrBitCast(CI, ValueTy);
21809}
21810
21812 IRBuilderBase &Builder) const {
21813 if (!Subtarget->hasV7Ops())
21814 return;
21815 Builder.CreateIntrinsic(Intrinsic::arm_clrex, {});
21816}
21817
21819 Value *Val, Value *Addr,
21820 AtomicOrdering Ord) const {
21821 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
21822 bool IsRelease = isReleaseOrStronger(Ord);
21823
21824 // Since the intrinsics must have legal type, the i64 intrinsics take two
21825 // parameters: "i32, i32". We must marshal Val into the appropriate form
21826 // before the call.
21827 if (Val->getType()->getPrimitiveSizeInBits() == 64) {
21829 IsRelease ? Intrinsic::arm_stlexd : Intrinsic::arm_strexd;
21830 Type *Int32Ty = Type::getInt32Ty(M->getContext());
21831
21832 Value *Lo = Builder.CreateTrunc(Val, Int32Ty, "lo");
21833 Value *Hi = Builder.CreateTrunc(Builder.CreateLShr(Val, 32), Int32Ty, "hi");
21834 if (!Subtarget->isLittle())
21835 std::swap(Lo, Hi);
21836 return Builder.CreateIntrinsic(Int, {Lo, Hi, Addr});
21837 }
21838
21839 Intrinsic::ID Int = IsRelease ? Intrinsic::arm_stlex : Intrinsic::arm_strex;
21840 Type *Tys[] = { Addr->getType() };
21842
21843 CallInst *CI = Builder.CreateCall(
21844 Strex, {Builder.CreateZExtOrBitCast(
21845 Val, Strex->getFunctionType()->getParamType(0)),
21846 Addr});
21847 CI->addParamAttr(1, Attribute::get(M->getContext(), Attribute::ElementType,
21848 Val->getType()));
21849 return CI;
21850}
21851
21852
21854 return Subtarget->isMClass();
21855}
21856
21857/// A helper function for determining the number of interleaved accesses we
21858/// will generate when lowering accesses of the given type.
21859unsigned
21861 const DataLayout &DL) const {
21862 return (DL.getTypeSizeInBits(VecTy) + 127) / 128;
21863}
21864
21866 unsigned Factor, FixedVectorType *VecTy, Align Alignment,
21867 const DataLayout &DL) const {
21868
21869 unsigned VecSize = DL.getTypeSizeInBits(VecTy);
21870 unsigned ElSize = DL.getTypeSizeInBits(VecTy->getElementType());
21871
21872 if (!Subtarget->hasNEON() && !Subtarget->hasMVEIntegerOps())
21873 return false;
21874
21875 // Ensure the vector doesn't have f16 elements. Even though we could do an
21876 // i16 vldN, we can't hold the f16 vectors and will end up converting via
21877 // f32.
21878 if (Subtarget->hasNEON() && VecTy->getElementType()->isHalfTy())
21879 return false;
21880 if (Subtarget->hasMVEIntegerOps() && Factor == 3)
21881 return false;
21882
21883 // Ensure the number of vector elements is greater than 1.
21884 if (VecTy->getNumElements() < 2)
21885 return false;
21886
21887 // Ensure the element type is legal.
21888 if (ElSize != 8 && ElSize != 16 && ElSize != 32)
21889 return false;
21890 // And the alignment if high enough under MVE.
21891 if (Subtarget->hasMVEIntegerOps() && Alignment < ElSize / 8)
21892 return false;
21893
21894 // Ensure the total vector size is 64 or a multiple of 128. Types larger than
21895 // 128 will be split into multiple interleaved accesses.
21896 if (Subtarget->hasNEON() && VecSize == 64)
21897 return true;
21898 return VecSize % 128 == 0;
21899}
21900
21902 if (Subtarget->hasNEON())
21903 return 4;
21904 if (Subtarget->hasMVEIntegerOps())
21907}
21908
21909/// Lower an interleaved load into a vldN intrinsic.
21910///
21911/// E.g. Lower an interleaved load (Factor = 2):
21912/// %wide.vec = load <8 x i32>, <8 x i32>* %ptr, align 4
21913/// %v0 = shuffle %wide.vec, undef, <0, 2, 4, 6> ; Extract even elements
21914/// %v1 = shuffle %wide.vec, undef, <1, 3, 5, 7> ; Extract odd elements
21915///
21916/// Into:
21917/// %vld2 = { <4 x i32>, <4 x i32> } call llvm.arm.neon.vld2(%ptr, 4)
21918/// %vec0 = extractelement { <4 x i32>, <4 x i32> } %vld2, i32 0
21919/// %vec1 = extractelement { <4 x i32>, <4 x i32> } %vld2, i32 1
21922 ArrayRef<unsigned> Indices, unsigned Factor, const APInt &GapMask) const {
21923 assert(Factor >= 2 && Factor <= getMaxSupportedInterleaveFactor() &&
21924 "Invalid interleave factor");
21925 assert(!Shuffles.empty() && "Empty shufflevector input");
21926 assert(Shuffles.size() == Indices.size() &&
21927 "Unmatched number of shufflevectors and indices");
21928
21929 auto *LI = dyn_cast<LoadInst>(Load);
21930 if (!LI)
21931 return false;
21932 assert(!Mask && GapMask.popcount() == Factor && "Unexpected mask on a load");
21933
21934 auto *VecTy = cast<FixedVectorType>(Shuffles[0]->getType());
21935 Type *EltTy = VecTy->getElementType();
21936
21937 const DataLayout &DL = LI->getDataLayout();
21938 Align Alignment = LI->getAlign();
21939
21940 // Skip if we do not have NEON and skip illegal vector types. We can
21941 // "legalize" wide vector types into multiple interleaved accesses as long as
21942 // the vector types are divisible by 128.
21943 if (!isLegalInterleavedAccessType(Factor, VecTy, Alignment, DL))
21944 return false;
21945
21946 unsigned NumLoads = getNumInterleavedAccesses(VecTy, DL);
21947
21948 // A pointer vector can not be the return type of the ldN intrinsics. Need to
21949 // load integer vectors first and then convert to pointer vectors.
21950 if (EltTy->isPointerTy())
21951 VecTy = FixedVectorType::get(DL.getIntPtrType(EltTy), VecTy);
21952
21953 IRBuilder<> Builder(LI);
21954
21955 // The base address of the load.
21956 Value *BaseAddr = LI->getPointerOperand();
21957
21958 if (NumLoads > 1) {
21959 // If we're going to generate more than one load, reset the sub-vector type
21960 // to something legal.
21961 VecTy = FixedVectorType::get(VecTy->getElementType(),
21962 VecTy->getNumElements() / NumLoads);
21963 }
21964
21965 assert(isTypeLegal(EVT::getEVT(VecTy)) && "Illegal vldN vector type!");
21966
21967 auto createLoadIntrinsic = [&](Value *BaseAddr) {
21968 if (Subtarget->hasNEON()) {
21969 Type *PtrTy = Builder.getPtrTy(LI->getPointerAddressSpace());
21970 Type *Tys[] = {VecTy, PtrTy};
21971 static const Intrinsic::ID LoadInts[3] = {Intrinsic::arm_neon_vld2,
21972 Intrinsic::arm_neon_vld3,
21973 Intrinsic::arm_neon_vld4};
21974
21976 Ops.push_back(BaseAddr);
21977 Ops.push_back(Builder.getInt32(LI->getAlign().value()));
21978
21979 return Builder.CreateIntrinsic(LoadInts[Factor - 2], Tys, Ops,
21980 /*FMFSource=*/nullptr, "vldN");
21981 } else {
21982 assert((Factor == 2 || Factor == 4) &&
21983 "expected interleave factor of 2 or 4 for MVE");
21984 Intrinsic::ID LoadInts =
21985 Factor == 2 ? Intrinsic::arm_mve_vld2q : Intrinsic::arm_mve_vld4q;
21986 Type *PtrTy = Builder.getPtrTy(LI->getPointerAddressSpace());
21987 Type *Tys[] = {VecTy, PtrTy};
21988
21990 Ops.push_back(BaseAddr);
21991 return Builder.CreateIntrinsic(LoadInts, Tys, Ops, /*FMFSource=*/nullptr,
21992 "vldN");
21993 }
21994 };
21995
21996 // Holds sub-vectors extracted from the load intrinsic return values. The
21997 // sub-vectors are associated with the shufflevector instructions they will
21998 // replace.
22000
22001 for (unsigned LoadCount = 0; LoadCount < NumLoads; ++LoadCount) {
22002 // If we're generating more than one load, compute the base address of
22003 // subsequent loads as an offset from the previous.
22004 if (LoadCount > 0)
22005 BaseAddr = Builder.CreateConstGEP1_32(VecTy->getElementType(), BaseAddr,
22006 VecTy->getNumElements() * Factor);
22007
22008 Value *VldN = createLoadIntrinsic(BaseAddr);
22009
22010 // Replace uses of each shufflevector with the corresponding vector loaded
22011 // by ldN.
22012 for (unsigned i = 0; i < Shuffles.size(); i++) {
22013 ShuffleVectorInst *SV = Shuffles[i];
22014 unsigned Index = Indices[i];
22015
22016 Value *SubVec = Builder.CreateExtractValue(VldN, Index);
22017
22018 // Convert the integer vector to pointer vector if the element is pointer.
22019 if (EltTy->isPointerTy())
22020 SubVec = Builder.CreateIntToPtr(
22021 SubVec,
22022 FixedVectorType::get(SV->getType()->getElementType(), VecTy));
22023
22024 SubVecs[SV].push_back(SubVec);
22025 }
22026 }
22027
22028 // Replace uses of the shufflevector instructions with the sub-vectors
22029 // returned by the load intrinsic. If a shufflevector instruction is
22030 // associated with more than one sub-vector, those sub-vectors will be
22031 // concatenated into a single wide vector.
22032 for (ShuffleVectorInst *SVI : Shuffles) {
22033 auto &SubVec = SubVecs[SVI];
22034 auto *WideVec =
22035 SubVec.size() > 1 ? concatenateVectors(Builder, SubVec) : SubVec[0];
22036 SVI->replaceAllUsesWith(WideVec);
22037 }
22038
22039 return true;
22040}
22041
22042/// Lower an interleaved store into a vstN intrinsic.
22043///
22044/// E.g. Lower an interleaved store (Factor = 3):
22045/// %i.vec = shuffle <8 x i32> %v0, <8 x i32> %v1,
22046/// <0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11>
22047/// store <12 x i32> %i.vec, <12 x i32>* %ptr, align 4
22048///
22049/// Into:
22050/// %sub.v0 = shuffle <8 x i32> %v0, <8 x i32> v1, <0, 1, 2, 3>
22051/// %sub.v1 = shuffle <8 x i32> %v0, <8 x i32> v1, <4, 5, 6, 7>
22052/// %sub.v2 = shuffle <8 x i32> %v0, <8 x i32> v1, <8, 9, 10, 11>
22053/// call void llvm.arm.neon.vst3(%ptr, %sub.v0, %sub.v1, %sub.v2, 4)
22054///
22055/// Note that the new shufflevectors will be removed and we'll only generate one
22056/// vst3 instruction in CodeGen.
22057///
22058/// Example for a more general valid mask (Factor 3). Lower:
22059/// %i.vec = shuffle <32 x i32> %v0, <32 x i32> %v1,
22060/// <4, 32, 16, 5, 33, 17, 6, 34, 18, 7, 35, 19>
22061/// store <12 x i32> %i.vec, <12 x i32>* %ptr
22062///
22063/// Into:
22064/// %sub.v0 = shuffle <32 x i32> %v0, <32 x i32> v1, <4, 5, 6, 7>
22065/// %sub.v1 = shuffle <32 x i32> %v0, <32 x i32> v1, <32, 33, 34, 35>
22066/// %sub.v2 = shuffle <32 x i32> %v0, <32 x i32> v1, <16, 17, 18, 19>
22067/// call void llvm.arm.neon.vst3(%ptr, %sub.v0, %sub.v1, %sub.v2, 4)
22069 Value *LaneMask,
22070 ShuffleVectorInst *SVI,
22071 unsigned Factor,
22072 const APInt &GapMask) const {
22073 assert(Factor >= 2 && Factor <= getMaxSupportedInterleaveFactor() &&
22074 "Invalid interleave factor");
22075 auto *SI = dyn_cast<StoreInst>(Store);
22076 if (!SI)
22077 return false;
22078 assert(!LaneMask && GapMask.popcount() == Factor &&
22079 "Unexpected mask on store");
22080
22081 auto *VecTy = cast<FixedVectorType>(SVI->getType());
22082 assert(VecTy->getNumElements() % Factor == 0 && "Invalid interleaved store");
22083
22084 unsigned LaneLen = VecTy->getNumElements() / Factor;
22085 Type *EltTy = VecTy->getElementType();
22086 auto *SubVecTy = FixedVectorType::get(EltTy, LaneLen);
22087
22088 const DataLayout &DL = SI->getDataLayout();
22089 Align Alignment = SI->getAlign();
22090
22091 // Skip if we do not have NEON and skip illegal vector types. We can
22092 // "legalize" wide vector types into multiple interleaved accesses as long as
22093 // the vector types are divisible by 128.
22094 if (!isLegalInterleavedAccessType(Factor, SubVecTy, Alignment, DL))
22095 return false;
22096
22097 unsigned NumStores = getNumInterleavedAccesses(SubVecTy, DL);
22098
22099 Value *Op0 = SVI->getOperand(0);
22100 Value *Op1 = SVI->getOperand(1);
22101 IRBuilder<> Builder(SI);
22102
22103 // StN intrinsics don't support pointer vectors as arguments. Convert pointer
22104 // vectors to integer vectors.
22105 if (EltTy->isPointerTy()) {
22106 Type *IntTy = DL.getIntPtrType(EltTy);
22107
22108 // Convert to the corresponding integer vector.
22109 auto *IntVecTy =
22111 Op0 = Builder.CreatePtrToInt(Op0, IntVecTy);
22112 Op1 = Builder.CreatePtrToInt(Op1, IntVecTy);
22113
22114 SubVecTy = FixedVectorType::get(IntTy, LaneLen);
22115 }
22116
22117 // The base address of the store.
22118 Value *BaseAddr = SI->getPointerOperand();
22119
22120 if (NumStores > 1) {
22121 // If we're going to generate more than one store, reset the lane length
22122 // and sub-vector type to something legal.
22123 LaneLen /= NumStores;
22124 SubVecTy = FixedVectorType::get(SubVecTy->getElementType(), LaneLen);
22125 }
22126
22127 assert(isTypeLegal(EVT::getEVT(SubVecTy)) && "Illegal vstN vector type!");
22128
22129 auto Mask = SVI->getShuffleMask();
22130
22131 auto createStoreIntrinsic = [&](Value *BaseAddr,
22132 SmallVectorImpl<Value *> &Shuffles) {
22133 if (Subtarget->hasNEON()) {
22134 static const Intrinsic::ID StoreInts[3] = {Intrinsic::arm_neon_vst2,
22135 Intrinsic::arm_neon_vst3,
22136 Intrinsic::arm_neon_vst4};
22137 Type *PtrTy = Builder.getPtrTy(SI->getPointerAddressSpace());
22138 Type *Tys[] = {PtrTy, SubVecTy};
22139
22141 Ops.push_back(BaseAddr);
22142 append_range(Ops, Shuffles);
22143 Ops.push_back(Builder.getInt32(SI->getAlign().value()));
22144 Builder.CreateIntrinsic(StoreInts[Factor - 2], Tys, Ops);
22145 } else {
22146 assert((Factor == 2 || Factor == 4) &&
22147 "expected interleave factor of 2 or 4 for MVE");
22148 Intrinsic::ID StoreInts =
22149 Factor == 2 ? Intrinsic::arm_mve_vst2q : Intrinsic::arm_mve_vst4q;
22150 Type *PtrTy = Builder.getPtrTy(SI->getPointerAddressSpace());
22151 Type *Tys[] = {PtrTy, SubVecTy};
22152
22154 Ops.push_back(BaseAddr);
22155 append_range(Ops, Shuffles);
22156 for (unsigned F = 0; F < Factor; F++) {
22157 Ops.push_back(Builder.getInt32(F));
22158 Builder.CreateIntrinsic(StoreInts, Tys, Ops);
22159 Ops.pop_back();
22160 }
22161 }
22162 };
22163
22164 for (unsigned StoreCount = 0; StoreCount < NumStores; ++StoreCount) {
22165 // If we generating more than one store, we compute the base address of
22166 // subsequent stores as an offset from the previous.
22167 if (StoreCount > 0)
22168 BaseAddr = Builder.CreateConstGEP1_32(SubVecTy->getElementType(),
22169 BaseAddr, LaneLen * Factor);
22170
22171 SmallVector<Value *, 4> Shuffles;
22172
22173 // Split the shufflevector operands into sub vectors for the new vstN call.
22174 for (unsigned i = 0; i < Factor; i++) {
22175 unsigned IdxI = StoreCount * LaneLen * Factor + i;
22176 if (Mask[IdxI] >= 0) {
22177 Shuffles.push_back(Builder.CreateShuffleVector(
22178 Op0, Op1, createSequentialMask(Mask[IdxI], LaneLen, 0)));
22179 } else {
22180 unsigned StartMask = 0;
22181 for (unsigned j = 1; j < LaneLen; j++) {
22182 unsigned IdxJ = StoreCount * LaneLen * Factor + j;
22183 if (Mask[IdxJ * Factor + IdxI] >= 0) {
22184 StartMask = Mask[IdxJ * Factor + IdxI] - IdxJ;
22185 break;
22186 }
22187 }
22188 // Note: If all elements in a chunk are undefs, StartMask=0!
22189 // Note: Filling undef gaps with random elements is ok, since
22190 // those elements were being written anyway (with undefs).
22191 // In the case of all undefs we're defaulting to using elems from 0
22192 // Note: StartMask cannot be negative, it's checked in
22193 // isReInterleaveMask
22194 Shuffles.push_back(Builder.CreateShuffleVector(
22195 Op0, Op1, createSequentialMask(StartMask, LaneLen, 0)));
22196 }
22197 }
22198
22199 createStoreIntrinsic(BaseAddr, Shuffles);
22200 }
22201 return true;
22202}
22203
22211
22213 uint64_t &Members) {
22214 if (auto *ST = dyn_cast<StructType>(Ty)) {
22215 for (unsigned i = 0; i < ST->getNumElements(); ++i) {
22216 uint64_t SubMembers = 0;
22217 if (!isHomogeneousAggregate(ST->getElementType(i), Base, SubMembers))
22218 return false;
22219 Members += SubMembers;
22220 }
22221 } else if (auto *AT = dyn_cast<ArrayType>(Ty)) {
22222 uint64_t SubMembers = 0;
22223 if (!isHomogeneousAggregate(AT->getElementType(), Base, SubMembers))
22224 return false;
22225 Members += SubMembers * AT->getNumElements();
22226 } else if (Ty->isFloatTy()) {
22227 if (Base != HA_UNKNOWN && Base != HA_FLOAT)
22228 return false;
22229 Members = 1;
22230 Base = HA_FLOAT;
22231 } else if (Ty->isDoubleTy()) {
22232 if (Base != HA_UNKNOWN && Base != HA_DOUBLE)
22233 return false;
22234 Members = 1;
22235 Base = HA_DOUBLE;
22236 } else if (auto *VT = dyn_cast<VectorType>(Ty)) {
22237 Members = 1;
22238 switch (Base) {
22239 case HA_FLOAT:
22240 case HA_DOUBLE:
22241 return false;
22242 case HA_VECT64:
22243 return VT->getPrimitiveSizeInBits().getFixedValue() == 64;
22244 case HA_VECT128:
22245 return VT->getPrimitiveSizeInBits().getFixedValue() == 128;
22246 case HA_UNKNOWN:
22247 switch (VT->getPrimitiveSizeInBits().getFixedValue()) {
22248 case 64:
22249 Base = HA_VECT64;
22250 return true;
22251 case 128:
22252 Base = HA_VECT128;
22253 return true;
22254 default:
22255 return false;
22256 }
22257 }
22258 }
22259
22260 return (Members > 0 && Members <= 4);
22261}
22262
22263/// Return the correct alignment for the current calling convention.
22265 Type *ArgTy, const DataLayout &DL) const {
22266 const Align ABITypeAlign = DL.getABITypeAlign(ArgTy);
22267 if (!ArgTy->isVectorTy())
22268 return ABITypeAlign;
22269
22270 // Avoid over-aligning vector parameters. It would require realigning the
22271 // stack and waste space for no real benefit.
22272 MaybeAlign StackAlign = DL.getStackAlignment();
22273 assert(StackAlign && "data layout string is missing stack alignment");
22274 return std::min(ABITypeAlign, *StackAlign);
22275}
22276
22277/// Return true if a type is an AAPCS-VFP homogeneous aggregate or one of
22278/// [N x i32] or [N x i64]. This allows front-ends to skip emitting padding when
22279/// passing according to AAPCS rules.
22281 Type *Ty, CallingConv::ID CallConv, bool isVarArg,
22282 const DataLayout &DL) const {
22283 if (getEffectiveCallingConv(CallConv, isVarArg) !=
22285 return false;
22286
22288 uint64_t Members = 0;
22289 bool IsHA = isHomogeneousAggregate(Ty, Base, Members);
22290 LLVM_DEBUG(dbgs() << "isHA: " << IsHA << " "; Ty->dump());
22291
22292 bool IsIntArray = Ty->isArrayTy() && Ty->getArrayElementType()->isIntegerTy();
22293 return IsHA || IsIntArray;
22294}
22295
22297 ExceptionHandling EH, const Constant *PersonalityFn) const {
22298 // Platforms which do not use SjLj EH may return values in these registers
22299 // via the personality function.
22300 return EH == ExceptionHandling::SjLj ? Register() : ARM::R0;
22301}
22302
22304 ExceptionHandling EH, const Constant *PersonalityFn) const {
22305 // Platforms which do not use SjLj EH may return values in these registers
22306 // via the personality function.
22307 return EH == ExceptionHandling::SjLj ? Register() : ARM::R1;
22308}
22309
22310void ARMTargetLowering::initializeSplitCSR(MachineBasicBlock *Entry) const {
22311 // Update IsSplitCSR in ARMFunctionInfo.
22312 ARMFunctionInfo *AFI = Entry->getParent()->getInfo<ARMFunctionInfo>();
22313 AFI->setIsSplitCSR(true);
22314}
22315
22316void ARMTargetLowering::insertCopiesSplitCSR(
22317 MachineBasicBlock *Entry,
22318 const SmallVectorImpl<MachineBasicBlock *> &Exits) const {
22319 const ARMBaseRegisterInfo *TRI = Subtarget->getRegisterInfo();
22320 const MCPhysReg *IStart = TRI->getCalleeSavedRegsViaCopy(Entry->getParent());
22321 if (!IStart)
22322 return;
22323
22324 const TargetInstrInfo *TII = Subtarget->getInstrInfo();
22325 MachineRegisterInfo *MRI = &Entry->getParent()->getRegInfo();
22326 MachineBasicBlock::iterator MBBI = Entry->begin();
22327 for (const MCPhysReg *I = IStart; *I; ++I) {
22328 const TargetRegisterClass *RC = nullptr;
22329 if (ARM::GPRRegClass.contains(*I))
22330 RC = &ARM::GPRRegClass;
22331 else if (ARM::DPRRegClass.contains(*I))
22332 RC = &ARM::DPRRegClass;
22333 else
22334 llvm_unreachable("Unexpected register class in CSRsViaCopy!");
22335
22336 Register NewVR = MRI->createVirtualRegister(RC);
22337 // Create copy from CSR to a virtual register.
22338 // FIXME: this currently does not emit CFI pseudo-instructions, it works
22339 // fine for CXX_FAST_TLS since the C++-style TLS access functions should be
22340 // nounwind. If we want to generalize this later, we may need to emit
22341 // CFI pseudo-instructions.
22342 assert(Entry->getParent()->getFunction().hasFnAttribute(
22343 Attribute::NoUnwind) &&
22344 "Function should be nounwind in insertCopiesSplitCSR!");
22345 Entry->addLiveIn(*I);
22346 BuildMI(*Entry, MBBI, DebugLoc(), TII->get(TargetOpcode::COPY), NewVR)
22347 .addReg(*I);
22348
22349 // Insert the copy-back instructions right before the terminator.
22350 for (auto *Exit : Exits)
22351 BuildMI(*Exit, Exit->getFirstTerminator(), DebugLoc(),
22352 TII->get(TargetOpcode::COPY), *I)
22353 .addReg(NewVR);
22354 }
22355}
22356
22361
22363 return Subtarget->hasMVEIntegerOps();
22364}
22365
22368 auto *VTy = dyn_cast<FixedVectorType>(Ty);
22369 if (!VTy)
22370 return false;
22371
22372 auto *ScalarTy = VTy->getScalarType();
22373 unsigned NumElements = VTy->getNumElements();
22374
22375 unsigned VTyWidth = VTy->getScalarSizeInBits() * NumElements;
22376 if (VTyWidth < 128 || !llvm::isPowerOf2_32(VTyWidth))
22377 return false;
22378
22379 // Both VCADD and VCMUL/VCMLA support the same types, F16 and F32
22380 if (ScalarTy->isHalfTy() || ScalarTy->isFloatTy())
22381 return Subtarget->hasMVEFloatOps();
22382
22384 return false;
22385
22386 return Subtarget->hasMVEIntegerOps() &&
22387 (ScalarTy->isIntegerTy(8) || ScalarTy->isIntegerTy(16) ||
22388 ScalarTy->isIntegerTy(32));
22389}
22390
22392 static const MCPhysReg RCRegs[] = {ARM::FPSCR_RM};
22393 return RCRegs;
22394}
22395
22398 ComplexDeinterleavingRotation Rotation, Value *InputA, Value *InputB,
22399 Value *Accumulator) const {
22400
22402
22403 unsigned TyWidth = Ty->getScalarSizeInBits() * Ty->getNumElements();
22404
22405 assert(TyWidth >= 128 && "Width of vector type must be at least 128 bits");
22406
22407 if (TyWidth > 128) {
22408 int Stride = Ty->getNumElements() / 2;
22409 auto SplitSeq = llvm::seq<int>(0, Ty->getNumElements());
22410 auto SplitSeqVec = llvm::to_vector(SplitSeq);
22411 ArrayRef<int> LowerSplitMask(&SplitSeqVec[0], Stride);
22412 ArrayRef<int> UpperSplitMask(&SplitSeqVec[Stride], Stride);
22413
22414 auto *LowerSplitA = B.CreateShuffleVector(InputA, LowerSplitMask);
22415 auto *LowerSplitB = B.CreateShuffleVector(InputB, LowerSplitMask);
22416 auto *UpperSplitA = B.CreateShuffleVector(InputA, UpperSplitMask);
22417 auto *UpperSplitB = B.CreateShuffleVector(InputB, UpperSplitMask);
22418 Value *LowerSplitAcc = nullptr;
22419 Value *UpperSplitAcc = nullptr;
22420
22421 if (Accumulator) {
22422 LowerSplitAcc = B.CreateShuffleVector(Accumulator, LowerSplitMask);
22423 UpperSplitAcc = B.CreateShuffleVector(Accumulator, UpperSplitMask);
22424 }
22425
22426 auto *LowerSplitInt = createComplexDeinterleavingIR(
22427 B, OperationType, Rotation, LowerSplitA, LowerSplitB, LowerSplitAcc);
22428 auto *UpperSplitInt = createComplexDeinterleavingIR(
22429 B, OperationType, Rotation, UpperSplitA, UpperSplitB, UpperSplitAcc);
22430
22431 ArrayRef<int> JoinMask(&SplitSeqVec[0], Ty->getNumElements());
22432 return B.CreateShuffleVector(LowerSplitInt, UpperSplitInt, JoinMask);
22433 }
22434
22435 auto *IntTy = Type::getInt32Ty(B.getContext());
22436
22437 ConstantInt *ConstRotation = nullptr;
22438 if (OperationType == ComplexDeinterleavingOperation::CMulPartial) {
22439 ConstRotation = ConstantInt::get(IntTy, (int)Rotation);
22440
22441 if (Accumulator)
22442 return B.CreateIntrinsic(Intrinsic::arm_mve_vcmlaq, Ty,
22443 {ConstRotation, Accumulator, InputB, InputA});
22444 return B.CreateIntrinsic(Intrinsic::arm_mve_vcmulq, Ty,
22445 {ConstRotation, InputB, InputA});
22446 }
22447
22448 if (OperationType == ComplexDeinterleavingOperation::CAdd) {
22449 // 1 means the value is not halved.
22450 auto *ConstHalving = ConstantInt::get(IntTy, 1);
22451
22453 ConstRotation = ConstantInt::get(IntTy, 0);
22455 ConstRotation = ConstantInt::get(IntTy, 1);
22456
22457 if (!ConstRotation)
22458 return nullptr; // Invalid rotation for arm_mve_vcaddq
22459
22460 return B.CreateIntrinsic(Intrinsic::arm_mve_vcaddq, Ty,
22461 {ConstHalving, ConstRotation, InputA, InputB});
22462 }
22463
22464 return nullptr;
22465}
static bool isAddSubSExt(SDValue N, SelectionDAG &DAG)
static bool isVShiftRImm(SDValue Op, EVT VT, bool isNarrow, int64_t &Cnt)
isVShiftRImm - Check if this is a valid build_vector for the immediate operand of a vector shift righ...
static bool isExtendedBUILD_VECTOR(SDValue N, SelectionDAG &DAG, bool isSigned)
static SDValue carryFlagToValue(SDValue Glue, EVT VT, SelectionDAG &DAG, bool Invert)
static SDValue overflowFlagToValue(SDValue Glue, EVT VT, SelectionDAG &DAG)
static bool isZeroExtended(SDValue N, SelectionDAG &DAG)
static bool isCMN(SDValue Op, ISD::CondCode CC, SelectionDAG &DAG)
static const MCPhysReg GPRArgRegs[]
static SDValue valueToCarryFlag(SDValue Value, SelectionDAG &DAG, bool Invert)
static SDValue GeneratePerfectShuffle(unsigned ID, SDValue V1, SDValue V2, unsigned PFEntry, SDValue LHS, SDValue RHS, SelectionDAG &DAG, const SDLoc &DL)
GeneratePerfectShuffle - Given an entry in the perfect-shuffle table, emit the specified operations t...
constexpr MVT FlagsVT
Value type used for NZCV flags.
static unsigned getCmpOperandFoldingProfit(SDValue Op, bool AllowExtend)
Returns how profitable it is to fold a comparison's operand's shift and/or extension operations.
static bool getVShiftImm(SDValue Op, unsigned ElementBits, int64_t &Cnt)
getVShiftImm - Check if this is a valid build_vector for the immediate operand of a vector shift oper...
static bool optimizeLogicalImm(SDValue Op, unsigned Size, uint64_t Imm, const APInt &Demanded, TargetLowering::TargetLoweringOpt &TLO, unsigned NewOpc)
static bool isSafeSignedCMN(SDValue Op, SelectionDAG &DAG)
static SDValue LowerPREFETCH(SDValue Op, SelectionDAG &DAG)
static bool isSignExtended(SDValue N, SelectionDAG &DAG)
static bool isAddSubZExt(SDValue N, SelectionDAG &DAG)
static bool isVShiftLImm(SDValue Op, EVT VT, bool isLong, int64_t &Cnt)
isVShiftLImm - Check if this is a valid build_vector for the immediate operand of a vector shift left...
static bool canGuaranteeTCO(CallingConv::ID CC, bool GuaranteeTailCalls)
Return true if the calling convention is one that we can guarantee TCO for.
unsigned RegSize
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
amdgpu aa AMDGPU Address space based Alias Analysis Wrapper
unsigned Imm
unsigned uint64_t
static bool isConstant(const MachineInstr &MI)
constexpr LLT F64
constexpr LLT S1
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file implements a class to represent arbitrary precision integral constant values and operations...
static SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG)
static bool isStore(int Opcode)
static bool isThumb(const MCSubtargetInfo &STI)
static SDValue PerformExtractEltToVMOVRRD(SDNode *N, TargetLowering::DAGCombinerInfo &DCI)
static bool isIncompatibleReg(const MCPhysReg &PR, MVT VT)
static SDValue PerformVQDMULHCombine(SDNode *N, SelectionDAG &DAG)
static SDValue LowerBUILD_VECTOR_i1(SDValue Op, SelectionDAG &DAG, const ARMSubtarget *ST)
static SDValue LowerShift(SDNode *N, SelectionDAG &DAG, const ARMSubtarget *ST)
static SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG, const ARMSubtarget *ST)
static SDValue AddRequiredExtensionForVMULL(SDValue N, SelectionDAG &DAG, const EVT &OrigTy, const EVT &ExtTy, unsigned ExtOpcode)
AddRequiredExtensionForVMULL - Add a sign/zero extension to extend the total value size to 64 bits.
static cl::opt< unsigned > ConstpoolPromotionMaxSize("arm-promote-constant-max-size", cl::Hidden, cl::desc("Maximum size of constant to promote into a constant pool"), cl::init(64))
static bool isZeroOrAllOnes(SDValue N, bool AllOnes)
static SDValue LowerINSERT_VECTOR_ELT_i1(SDValue Op, SelectionDAG &DAG, const ARMSubtarget *ST)
static bool isVTBLMask(ArrayRef< int > M, EVT VT)
static SDValue PerformSUBCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
PerformSUBCombine - Target-specific dag combine xforms for ISD::SUB.
static cl::opt< bool > EnableConstpoolPromotion("arm-promote-constant", cl::Hidden, cl::desc("Enable / disable promotion of unnamed_addr constants into " "constant pools"), cl::init(false))
static SDValue PerformFAddVSelectCombine(SDNode *N, SelectionDAG &DAG, const ARMSubtarget *Subtarget)
static SDValue PerformExtractFpToIntStores(StoreSDNode *St, SelectionDAG &DAG)
static SDValue PerformVDUPCombine(SDNode *N, SelectionDAG &DAG, const ARMSubtarget *Subtarget)
PerformVDUPCombine - Target-specific dag combine xforms for ARMISD::VDUP.
static SDValue PerformExtractEltCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *ST)
static const APInt * isPowerOf2Constant(SDValue V)
static SDValue PerformVCVTCombine(SDNode *N, SelectionDAG &DAG, const ARMSubtarget *Subtarget)
PerformVCVTCombine - VCVT (floating-point to fixed-point, Advanced SIMD) can replace combinations of ...
static SDValue PerformVMOVhrCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI)
static SDValue LowerVectorFP_TO_INT(SDValue Op, SelectionDAG &DAG)
static SDValue LowerVECTOR_SHUFFLEUsingOneOff(SDValue Op, ArrayRef< int > ShuffleMask, SelectionDAG &DAG)
static bool isValidMVECond(unsigned CC, bool IsFloat)
static SDValue PerformPREDICATE_CASTCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI)
static ARMCC::CondCodes IntCCToARMCC(ISD::CondCode CC)
IntCCToARMCC - Convert a DAG integer condition code to an ARM CC.
static SDValue PerformSTORECombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
PerformSTORECombine - Target-specific dag combine xforms for ISD::STORE.
static SDValue LowerCONCAT_VECTORS(SDValue Op, SelectionDAG &DAG, const ARMSubtarget *ST)
static bool isGTorGE(ISD::CondCode CC)
static bool CombineVLDDUP(SDNode *N, TargetLowering::DAGCombinerInfo &DCI)
CombineVLDDUP - For a VDUPLANE node N, check if its source operand is a vldN-lane (N > 1) intrinsic,...
static SDValue ParseBFI(SDNode *N, APInt &ToMask, APInt &FromMask)
static bool isReverseMask(ArrayRef< int > M, EVT VT)
static bool isVZIP_v_undef_Mask(ArrayRef< int > M, EVT VT, unsigned &WhichResult)
isVZIP_v_undef_Mask - Special case of isVZIPMask for canonical form of "vector_shuffle v,...
static SDValue PerformSELECTCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
static SDValue AddCombineTo64bitUMAAL(SDNode *AddeNode, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
static SDValue PerformVECTOR_REG_CASTCombine(SDNode *N, SelectionDAG &DAG, const ARMSubtarget *ST)
static SDValue PerformVMulVCTPCombine(SDNode *N, SelectionDAG &DAG, const ARMSubtarget *Subtarget)
PerformVMulVCTPCombine - VCVT (fixed-point to floating-point, Advanced SIMD) can replace combinations...
static SDValue createGPRPairNode2xi32(SelectionDAG &DAG, SDValue V0, SDValue V1)
static SDValue bitcastf32Toi32(SDValue Op, SelectionDAG &DAG)
static bool findPointerConstIncrement(SDNode *N, SDValue *Ptr, SDValue *CInc)
static bool isVTRNMask(ArrayRef< int > M, EVT VT, unsigned &WhichResult)
static SDValue LowerEXTRACT_SUBVECTOR(SDValue Op, SelectionDAG &DAG, const ARMSubtarget *ST)
static bool CanInvertMVEVCMP(SDValue N)
static SDValue PerformLongShiftCombine(SDNode *N, SelectionDAG &DAG)
static SDValue AddCombineToVPADD(SDNode *N, SDValue N0, SDValue N1, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
static SDValue PerformShiftCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *ST)
PerformShiftCombine - Checks for immediate versions of vector shifts and lowers them.
static void FPCCToARMCC(ISD::CondCode CC, ARMCC::CondCodes &CondCode, ARMCC::CondCodes &CondCode2)
FPCCToARMCC - Convert a DAG fp condition code to an ARM CC.
static void ExpandREAD_REGISTER(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG)
static EVT getVectorTyFromPredicateVector(EVT VT)
static SDValue PerformFADDVCMLACombine(SDNode *N, SelectionDAG &DAG)
static SDValue handleCMSEValue(const SDValue &Value, const ISD::InputArg &Arg, SelectionDAG &DAG, const SDLoc &DL)
static SDValue PerformARMBUILD_VECTORCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI)
Target-specific dag combine xforms for ARMISD::BUILD_VECTOR.
static bool isSRL16(const SDValue &Op)
static SDValue PerformVMOVrhCombine(SDNode *N, SelectionDAG &DAG)
static SDValue PerformLOADCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
static SDValue IsCMPZCSINC(SDNode *Cmp, ARMCC::CondCodes &CC)
static unsigned getPointerConstIncrement(unsigned Opcode, SDValue Ptr, SDValue Inc, const SelectionDAG &DAG)
static SDValue combineSelectAndUseCommutative(SDNode *N, bool AllOnes, TargetLowering::DAGCombinerInfo &DCI)
static SDValue LowerATOMIC_FENCE(SDValue Op, SelectionDAG &DAG, const ARMSubtarget *Subtarget)
static Register genTPEntry(MachineBasicBlock *TpEntry, MachineBasicBlock *TpLoopBody, MachineBasicBlock *TpExit, Register OpSizeReg, const TargetInstrInfo *TII, DebugLoc Dl, MachineRegisterInfo &MRI)
Adds logic in loop entry MBB to calculate loop iteration count and adds t2WhileLoopSetup and t2WhileL...
static SDValue createGPRPairNodei64(SelectionDAG &DAG, SDValue V)
static bool isLTorLE(ISD::CondCode CC)
static SDValue PerformVCMPCombine(SDNode *N, SelectionDAG &DAG, const ARMSubtarget *Subtarget)
static SDValue PerformMVEVMULLCombine(SDNode *N, SelectionDAG &DAG, const ARMSubtarget *Subtarget)
static SDValue LowerSDIV_v4i16(SDValue N0, SDValue N1, const SDLoc &dl, SelectionDAG &DAG)
static SDValue performNegCMovCombine(SDNode *N, SelectionDAG &DAG)
static EVT getExtensionTo64Bits(const EVT &OrigVT)
static SDValue PerformBITCASTCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *ST)
static SDValue AddCombineTo64bitMLAL(SDNode *AddeSubeNode, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
static SDValue LowerWRITE_REGISTER(SDValue Op, SelectionDAG &DAG)
static bool checkAndUpdateCPSRKill(MachineBasicBlock::iterator SelectItr, MachineBasicBlock *BB, const TargetRegisterInfo *TRI)
static SDValue PerformCMPZCombine(SDNode *N, SelectionDAG &DAG)
static bool hasNormalLoadOperand(SDNode *N)
hasNormalLoadOperand - Check if any of the operands of a BUILD_VECTOR node are normal,...
static SDValue PerformInsertEltCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI)
PerformInsertEltCombine - Target-specific dag combine xforms for ISD::INSERT_VECTOR_ELT.
static SDValue PerformVDUPLANECombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
PerformVDUPLANECombine - Target-specific dag combine xforms for ARMISD::VDUPLANE.
static SDValue LowerBuildVectorOfFPTrunc(SDValue BV, SelectionDAG &DAG, const ARMSubtarget *ST)
static cl::opt< unsigned > ConstpoolPromotionMaxTotal("arm-promote-constant-max-total", cl::Hidden, cl::desc("Maximum size of ALL constants to promote into a constant pool"), cl::init(128))
static SDValue LowerTruncatei1(SDNode *N, SelectionDAG &DAG, const ARMSubtarget *ST)
static RTLIB::Libcall getDivRemLibcall(const SDNode *N, MVT::SimpleValueType SVT)
static SDValue SkipLoadExtensionForVMULL(LoadSDNode *LD, SelectionDAG &DAG)
SkipLoadExtensionForVMULL - return a load of the original vector size that does not do any sign/zero ...
static SDValue AddCombineVUZPToVPADDL(SDNode *N, SDValue N0, SDValue N1, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
static SDValue PerformADDCombineWithOperands(SDNode *N, SDValue N0, SDValue N1, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
PerformADDCombineWithOperands - Try DAG combinations for an ADD with operands N0 and N1.
static SDValue PromoteMVEPredVector(SDLoc dl, SDValue Pred, EVT VT, SelectionDAG &DAG)
static SDValue matchCSET(unsigned &Opcode, bool &InvertCond, SDValue TrueVal, SDValue FalseVal, const ARMSubtarget *Subtarget)
static bool isVZIPMask(ArrayRef< int > M, EVT VT, unsigned &WhichResult)
static SDValue PerformORCombineToSMULWBT(SDNode *OR, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
static bool isVTRN_v_undef_Mask(ArrayRef< int > M, EVT VT, unsigned &WhichResult)
isVTRN_v_undef_Mask - Special case of isVTRNMask for canonical form of "vector_shuffle v,...
static SDValue LowerUDIV(SDValue Op, SelectionDAG &DAG, const ARMSubtarget *ST)
static SDValue FindBFIToCombineWith(SDNode *N)
static SDValue LowerADDSUBSAT(SDValue Op, SelectionDAG &DAG, const ARMSubtarget *Subtarget)
static void checkVSELConstraints(ISD::CondCode CC, ARMCC::CondCodes &CondCode, bool &swpCmpOps, bool &swpVselOps)
static void ReplaceLongIntrinsic(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG)
static bool isS16(const SDValue &Op, SelectionDAG &DAG)
static bool isSRA16(const SDValue &Op)
static SDValue AddCombineBUILD_VECTORToVPADDL(SDNode *N, SDValue N0, SDValue N1, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
static SDValue LowerVECTOR_SHUFFLEUsingMovs(SDValue Op, ArrayRef< int > ShuffleMask, SelectionDAG &DAG)
static SDValue LowerInterruptReturn(SmallVectorImpl< SDValue > &RetOps, const SDLoc &DL, SelectionDAG &DAG)
static SDValue LowerEXTRACT_VECTOR_ELT_i1(SDValue Op, SelectionDAG &DAG, const ARMSubtarget *ST)
static SDValue getInvertedARMCondCode(SDValue ARMcc, SelectionDAG &DAG)
static SDValue LowerSDIV_v4i8(SDValue X, SDValue Y, const SDLoc &dl, SelectionDAG &DAG)
static void expandf64Toi32(SDValue Op, SelectionDAG &DAG, SDValue &RetVal1, SDValue &RetVal2)
static SDValue LowerCONCAT_VECTORS_i1(SDValue Op, SelectionDAG &DAG, const ARMSubtarget *ST)
static SDValue LowerCTTZ(SDNode *N, SelectionDAG &DAG, const ARMSubtarget *ST)
static SDValue PerformVLDCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI)
static bool isSHL16(const SDValue &Op)
static bool isVEXTMask(ArrayRef< int > M, EVT VT, bool &ReverseVEXT, unsigned &Imm)
static SDValue PerformMVEVLDCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI)
cl::opt< unsigned > ArmMaxBaseUpdatesToCheck("arm-max-base-updates-to-check", cl::Hidden, cl::desc("Maximum number of base-updates to check generating postindex."), cl::init(64))
static bool isTruncMask(ArrayRef< int > M, EVT VT, bool Top, bool SingleSource)
static SDValue PerformADDCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
PerformADDCombine - Target-specific dag combine xforms for ISD::ADD.
static unsigned getLdOpcode(unsigned LdSize, bool IsThumb1, bool IsThumb2)
Return the load opcode for a given load size.
static SDValue LowerADDSUBO_CARRY(SDValue Op, SelectionDAG &DAG, unsigned Opcode, bool IsSigned)
static bool isLegalT2AddressImmediate(int64_t V, EVT VT, const ARMSubtarget *Subtarget)
static bool isLegalMVEShuffleOp(unsigned PFEntry)
static SDValue PerformSignExtendInregCombine(SDNode *N, SelectionDAG &DAG)
static SDValue PerformShuffleVMOVNCombine(ShuffleVectorSDNode *N, SelectionDAG &DAG)
static bool isVUZPMask(ArrayRef< int > M, EVT VT, unsigned &WhichResult)
static SDValue PerformVECTOR_SHUFFLECombine(SDNode *N, SelectionDAG &DAG)
PerformVECTOR_SHUFFLECombine - Target-specific dag combine xforms for ISD::VECTOR_SHUFFLE.
static SDValue SkipExtensionForVMULL(SDNode *N, SelectionDAG &DAG)
SkipExtensionForVMULL - For a node that is a SIGN_EXTEND, ZERO_EXTEND, ANY_EXTEND,...
static int getNegationCost(SDValue Op)
static bool isVMOVNTruncMask(ArrayRef< int > M, EVT ToVT, bool rev)
static SDValue PerformVQMOVNCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI)
static MachineBasicBlock * OtherSucc(MachineBasicBlock *MBB, MachineBasicBlock *Succ)
static SDValue LowerVecReduceMinMax(SDValue Op, SelectionDAG &DAG, const ARMSubtarget *ST)
static SDValue PerformFPExtendCombine(SDNode *N, SelectionDAG &DAG, const ARMSubtarget *ST)
static SDValue PerformAddcSubcCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
static SDValue PerformVSELECTCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
static TargetLowering::ArgListTy getDivRemArgList(const SDNode *N, LLVMContext *Context, const ARMSubtarget *Subtarget)
static SDValue PerformVECREDUCE_ADDCombine(SDNode *N, SelectionDAG &DAG, const ARMSubtarget *ST)
static SDValue getZeroVector(EVT VT, SelectionDAG &DAG, const SDLoc &dl)
getZeroVector - Returns a vector of specified type with all zero elements.
static SDValue LowerAtomicLoadStore(SDValue Op, SelectionDAG &DAG)
static SDValue PerformSplittingToNarrowingStores(StoreSDNode *St, SelectionDAG &DAG)
static bool getT2IndexedAddressParts(SDNode *Ptr, EVT VT, bool isSEXTLoad, SDValue &Base, SDValue &Offset, bool &isInc, SelectionDAG &DAG)
static ARMCC::CondCodes getVCMPCondCode(SDValue N)
static cl::opt< bool > ARMInterworking("arm-interworking", cl::Hidden, cl::desc("Enable / disable ARM interworking (for debugging only)"), cl::init(true))
static void ReplaceREADCYCLECOUNTER(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG, const ARMSubtarget *Subtarget)
static SDValue PerformORCombineToBFI(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
static bool isConditionalZeroOrAllOnes(SDNode *N, bool AllOnes, SDValue &CC, bool &Invert, SDValue &OtherOp, SelectionDAG &DAG)
static SDValue LowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG, const ARMSubtarget *ST)
static SDValue PerformVSetCCToVCTPCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
static SDValue LowerBUILD_VECTORToVIDUP(SDValue Op, SelectionDAG &DAG, const ARMSubtarget *ST)
static bool isZeroVector(SDValue N)
static SDValue PerformAddeSubeCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
static void ReplaceCMP_SWAP_64Results(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG)
static bool isLowerSaturate(const SDValue LHS, const SDValue RHS, const SDValue TrueVal, const SDValue FalseVal, const ISD::CondCode CC, const SDValue K)
static bool isLegalLogicalImmediate(unsigned Imm, const ARMSubtarget *Subtarget)
static SDValue LowerPredicateLoad(SDValue Op, SelectionDAG &DAG)
static void emitPostSt(MachineBasicBlock *BB, MachineBasicBlock::iterator Pos, const TargetInstrInfo *TII, const DebugLoc &dl, unsigned StSize, unsigned Data, unsigned AddrIn, unsigned AddrOut, bool IsThumb1, bool IsThumb2)
Emit a post-increment store operation with given size.
static bool isVMOVNMask(ArrayRef< int > M, EVT VT, bool Top, bool SingleSource)
static SDValue CombineBaseUpdate(SDNode *N, TargetLowering::DAGCombinerInfo &DCI)
CombineBaseUpdate - Target-specific DAG combine function for VLDDUP, NEON load/store intrinsics,...
static SDValue LowerSaturatingConditional(SDValue Op, SelectionDAG &DAG)
static SDValue PerformSubCSINCCombine(SDNode *N, SelectionDAG &DAG)
static SDValue PerformVMOVRRDCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
PerformVMOVRRDCombine - Target-specific dag combine xforms for ARMISD::VMOVRRD.
static SDValue LowerFP_TO_INT_SAT(SDValue Op, SelectionDAG &DAG, const ARMSubtarget *Subtarget)
static SDValue PerformCSETCombine(SDNode *N, SelectionDAG &DAG)
static SDValue PerformVMOVNCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI)
static SDValue PerformInsertSubvectorCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI)
static SDValue LowerVectorExtend(SDNode *N, SelectionDAG &DAG, const ARMSubtarget *Subtarget)
static SDValue WinDBZCheckDenominator(SelectionDAG &DAG, SDNode *N, SDValue InChain)
static SDValue LowerVECTOR_SHUFFLEv8i8(SDValue Op, ArrayRef< int > ShuffleMask, SelectionDAG &DAG)
static SDValue PerformVMULCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
PerformVMULCombine Distribute (A + B) * C to (A * C) + (B * C) to take advantage of the special multi...
static SDValue LowerMUL(SDValue Op, SelectionDAG &DAG)
static SDValue PerformBFICombine(SDNode *N, SelectionDAG &DAG)
static SDValue PerformORCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
PerformORCombine - Target-specific dag combine xforms for ISD::OR.
static SDValue LowerMLOAD(SDValue Op, SelectionDAG &DAG)
static SDValue PerformTruncatingStoreCombine(StoreSDNode *St, SelectionDAG &DAG)
static unsigned SelectPairHalf(unsigned Elements, ArrayRef< int > Mask, unsigned Index)
static void emitPostLd(MachineBasicBlock *BB, MachineBasicBlock::iterator Pos, const TargetInstrInfo *TII, const DebugLoc &dl, unsigned LdSize, unsigned Data, unsigned AddrIn, unsigned AddrOut, bool IsThumb1, bool IsThumb2)
Emit a post-increment load operation with given size.
static SDValue TryDistrubutionADDVecReduce(SDNode *N, SelectionDAG &DAG)
static bool isValidBaseUpdate(SDNode *N, SDNode *User)
static SDValue IsSingleInstrConstant(SDValue N, SelectionDAG &DAG, const ARMSubtarget *ST, const SDLoc &dl)
static bool IsQRMVEInstruction(const SDNode *N, const SDNode *Op)
static SDValue PerformMinMaxToSatCombine(SDValue Op, SelectionDAG &DAG, const ARMSubtarget *Subtarget)
static SDValue PerformXORCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
static bool getMVEIndexedAddressParts(SDNode *Ptr, EVT VT, Align Alignment, bool isSEXTLoad, bool IsMasked, bool isLE, SDValue &Base, SDValue &Offset, bool &isInc, SelectionDAG &DAG)
std::pair< unsigned, const TargetRegisterClass * > RCPair
static SDValue combineSelectAndUse(SDNode *N, SDValue Slct, SDValue OtherOp, TargetLowering::DAGCombinerInfo &DCI, bool AllOnes=false)
static SDValue PerformExtendCombine(SDNode *N, SelectionDAG &DAG, const ARMSubtarget *ST)
PerformExtendCombine - Target-specific DAG combining for ISD::SIGN_EXTEND, ISD::ZERO_EXTEND,...
static SDValue LowerSDIV(SDValue Op, SelectionDAG &DAG, const ARMSubtarget *ST)
cl::opt< unsigned > MVEMaxSupportedInterleaveFactor("mve-max-interleave-factor", cl::Hidden, cl::desc("Maximum interleave factor for MVE VLDn to generate."), cl::init(2))
static SDValue isVMOVModifiedImm(uint64_t SplatBits, uint64_t SplatUndef, unsigned SplatBitSize, SelectionDAG &DAG, const SDLoc &dl, EVT &VT, EVT VectorVT, VMOVModImmType type)
isVMOVModifiedImm - Check if the specified splat value corresponds to a valid vector constant for a N...
static SDValue LowerBuildVectorOfFPExt(SDValue BV, SelectionDAG &DAG, const ARMSubtarget *ST)
static SDValue CombineVMOVDRRCandidateWithVecOp(const SDNode *BC, SelectionDAG &DAG)
BC is a bitcast that is about to be turned into a VMOVDRR.
static SDValue promoteToConstantPool(const ARMTargetLowering *TLI, const GlobalValue *GV, SelectionDAG &DAG, EVT PtrVT, const SDLoc &dl)
static unsigned isNEONTwoResultShuffleMask(ArrayRef< int > ShuffleMask, EVT VT, unsigned &WhichResult, bool &isV_UNDEF)
Check if ShuffleMask is a NEON two-result shuffle (VZIP, VUZP, VTRN), and return the corresponding AR...
static bool BitsProperlyConcatenate(const APInt &A, const APInt &B)
static bool getARMIndexedAddressParts(SDNode *Ptr, EVT VT, bool isSEXTLoad, SDValue &Base, SDValue &Offset, bool &isInc, SelectionDAG &DAG)
static SDValue LowerVecReduce(SDValue Op, SelectionDAG &DAG, const ARMSubtarget *ST)
static SDValue LowerVectorINT_TO_FP(SDValue Op, SelectionDAG &DAG)
static bool TryCombineBaseUpdate(struct BaseUpdateTarget &Target, struct BaseUpdateUser &User, bool SimpleConstIncOnly, TargetLowering::DAGCombinerInfo &DCI)
static bool allUsersAreInFunction(const Value *V, const Function *F)
Return true if all users of V are within function F, looking through ConstantExprs.
static bool isSingletonVEXTMask(ArrayRef< int > M, EVT VT, unsigned &Imm)
static SDValue PerformVMOVDRRCombine(SDNode *N, SelectionDAG &DAG)
PerformVMOVDRRCombine - Target-specific dag combine xforms for ARMISD::VMOVDRR.
static bool isLowerSaturatingConditional(const SDValue &Op, SDValue &V, SDValue &SatK)
static bool isLegalAddressImmediate(int64_t V, EVT VT, const ARMSubtarget *Subtarget)
isLegalAddressImmediate - Return true if the integer value can be used as the offset of the target ad...
static SDValue LowerVSETCC(SDValue Op, SelectionDAG &DAG, const ARMSubtarget *ST)
static bool isLegalT1AddressImmediate(int64_t V, EVT VT)
static SDValue CombineANDShift(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
static SDValue LowerSETCCCARRY(SDValue Op, SelectionDAG &DAG)
static SDValue PerformSHLSimplify(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *ST)
static SDValue PerformADDECombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
PerformADDECombine - Target-specific dag combine transform from ARMISD::ADDC, ARMISD::ADDE,...
static SDValue PerformReduceShuffleCombine(SDNode *N, SelectionDAG &DAG)
static SDValue PerformUMLALCombine(SDNode *N, SelectionDAG &DAG, const ARMSubtarget *Subtarget)
static SDValue LowerTruncate(SDNode *N, SelectionDAG &DAG, const ARMSubtarget *Subtarget)
static SDValue PerformHWLoopCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *ST)
static SDValue PerformORCombineToShiftInsert(SelectionDAG &DAG, SDValue AndOp, SDValue ShiftOp, EVT VT, SDLoc dl)
static SDValue PerformSplittingMVETruncToNarrowingStores(StoreSDNode *St, SelectionDAG &DAG)
static bool isVUZP_v_undef_Mask(ArrayRef< int > M, EVT VT, unsigned &WhichResult)
isVUZP_v_undef_Mask - Special case of isVUZPMask for canonical form of "vector_shuffle v,...
static bool isHomogeneousAggregate(Type *Ty, HABaseType &Base, uint64_t &Members)
static SDValue PerformMULCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
static SDValue PerformFADDCombine(SDNode *N, SelectionDAG &DAG, const ARMSubtarget *Subtarget)
static SDValue LowerReverse_VECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG)
static SDValue PerformANDCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
static SDValue PerformADDVecReduce(SDNode *N, SelectionDAG &DAG, const ARMSubtarget *Subtarget)
static SDValue LowerPredicateStore(SDValue Op, SelectionDAG &DAG)
static SDValue SearchLoopIntrinsic(SDValue N, ISD::CondCode &CC, int &Imm, bool &Negate)
static bool canChangeToInt(SDValue Op, bool &SeenZero, const ARMSubtarget *Subtarget)
canChangeToInt - Given the fp compare operand, return true if it is suitable to morph to an integer c...
static unsigned getStOpcode(unsigned StSize, bool IsThumb1, bool IsThumb2)
Return the store opcode for a given store size.
static bool IsVUZPShuffleNode(SDNode *N)
static SDValue Expand64BitShift(SDNode *N, SelectionDAG &DAG, const ARMSubtarget *ST)
static SDValue AddCombineTo64BitSMLAL16(SDNode *AddcNode, SDNode *AddeNode, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
static void attachMEMCPYScratchRegs(const ARMSubtarget *Subtarget, MachineInstr &MI, const SDNode *Node)
Attaches vregs to MEMCPY that it will use as scratch registers when it is expanded into LDM/STM.
static bool isFloatingPointZero(SDValue Op)
isFloatingPointZero - Return true if this is +0.0.
static SDValue findMUL_LOHI(SDValue V)
static SDValue LowerVECTOR_SHUFFLE_i1(SDValue Op, SelectionDAG &DAG, const ARMSubtarget *ST)
static SDValue PerformORCombine_i1(SDNode *N, SelectionDAG &DAG, const ARMSubtarget *Subtarget)
static SDValue PerformSplittingMVEEXTToWideningLoad(SDNode *N, SelectionDAG &DAG)
static SDValue PerformSplittingToWideningLoad(SDNode *N, SelectionDAG &DAG)
static void genTPLoopBody(MachineBasicBlock *TpLoopBody, MachineBasicBlock *TpEntry, MachineBasicBlock *TpExit, const TargetInstrInfo *TII, DebugLoc Dl, MachineRegisterInfo &MRI, Register OpSrcReg, Register OpDestReg, Register ElementCountReg, Register TotalIterationsReg, bool IsMemcpy)
Adds logic in the loopBody MBB to generate MVE_VCTP, t2DoLoopDec and t2DoLoopEnd.
static SDValue PerformBUILD_VECTORCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
PerformBUILD_VECTORCombine - Target-specific dag combine xforms for ISD::BUILD_VECTOR.
static SDValue LowerVecReduceF(SDValue Op, SelectionDAG &DAG, const ARMSubtarget *ST)
static SDValue PerformMinMaxCombine(SDNode *N, SelectionDAG &DAG, const ARMSubtarget *ST)
PerformMinMaxCombine - Target-specific DAG combining for creating truncating saturates.
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
This file a TargetTransformInfoImplBase conforming object specific to the ARM target machine.
Function Alias Analysis false
Function Alias Analysis Results
Atomic ordering constants.
This file contains the simple types necessary to represent the attributes associated with functions a...
#define X(NUM, ENUM, NAME)
Definition ELF.h:857
This file implements the BitVector class.
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static std::optional< bool > isBigEndian(const SmallDenseMap< int64_t, int64_t, 8 > &MemOffset2Idx, int64_t LowestIdx)
Given a map from byte offsets in memory to indices in a load/store, determine if that map corresponds...
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static void createLoadIntrinsic(IntrinsicInst *II, LoadInst *LI, dxil::ResourceTypeInfo &RTI)
static void createStoreIntrinsic(IntrinsicInst *II, StoreInst *SI, dxil::ResourceTypeInfo &RTI)
This file defines the DenseMap class.
static bool isSigned(unsigned Opcode)
#define Check(C,...)
#define op(i)
#define im(i)
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
Module.h This file contains the declarations for the Module class.
std::pair< Value *, Value * > ShuffleOps
We are building a shuffle to create V, which is a sequence of insertelement, extractelement pairs.
static Value * LowerCTPOP(LLVMContext &Context, Value *V, Instruction *IP)
Emit the code to lower ctpop of V before the specified instruction IP.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
#define RegName(no)
static LVOptions Options
Definition LVOptions.cpp:25
lazy value info
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
#define G(x, y, z)
Definition MD5.cpp:55
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
Register Reg
Register const TargetRegisterInfo * TRI
Promote Memory to Register
Definition Mem2Reg.cpp:110
#define T
nvptx lower args
uint64_t High
uint64_t IntrinsicInst * II
PowerPC Reduce CR logical Operation
R600 Clause Merge
const SmallVectorImpl< MachineOperand > & Cond
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
SI Lower i1 Copies
Func MI getDebugLoc()))
This file contains some templates that are useful if you are working with the STL at all.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Definition Value.cpp:484
static cl::opt< unsigned > MaxSteps("has-predecessor-max-steps", cl::Hidden, cl::init(8192), cl::desc("DAG combiner limit number of steps when searching DAG " "for predecessor nodes"))
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition Statistic.h:171
This file contains some functions that are useful when dealing with strings.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
#define LLVM_DEBUG(...)
Definition Debug.h:119
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static SymbolRef::Type getType(const Symbol *Sym)
Definition TapiFile.cpp:39
This file describes how to lower LLVM code to machine code.
static X86::CondCode getSwappedCondition(X86::CondCode CC)
Assuming the flags are set by MI(a,b), return the condition code if we modify the instructions such t...
static constexpr int Concat[]
Value * RHS
Value * LHS
BinaryOperator * Mul
static bool isIntrinsic(const CallBase &Call, Intrinsic::ID ID)
The Input class is used to parse a yaml document into in-memory structs and vectors.
static constexpr roundingMode rmTowardZero
Definition APFloat.h:365
LLVM_ABI bool getExactInverse(APFloat *Inv) const
If this value is normal and has an exact, normal, multiplicative inverse, store it in inv and return ...
Definition APFloat.cpp:5976
APInt bitcastToAPInt() const
Definition APFloat.h:1475
opStatus convertToInteger(MutableArrayRef< integerPart > Input, unsigned int Width, bool IsSigned, roundingMode RM, bool *IsExact) const
Definition APFloat.h:1436
Class for arbitrary precision integers.
Definition APInt.h:78
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
Definition APInt.h:230
bool isMinSignedValue() const
Determine if this is the smallest signed value.
Definition APInt.h:419
uint64_t getZExtValue() const
Get zero extended value.
Definition APInt.h:1560
unsigned popcount() const
Count the number of bits set.
Definition APInt.h:1690
LLVM_ABI APInt zextOrTrunc(unsigned width) const
Zero extend or truncate to width.
Definition APInt.cpp:1078
unsigned getActiveBits() const
Compute the number of active bits in the value.
Definition APInt.h:1532
LLVM_ABI APInt trunc(unsigned width) const
Truncate to new width.
Definition APInt.cpp:970
void setBit(unsigned BitPosition)
Set the given bit to 1 whose position is given as "bitPosition".
Definition APInt.h:1350
bool sgt(const APInt &RHS) const
Signed greater than comparison.
Definition APInt.h:1205
bool isAllOnes() const
Determine if all bits are set. This is true for zero-width values.
Definition APInt.h:367
unsigned getBitWidth() const
Return the number of bits in the APInt.
Definition APInt.h:1508
bool ult(const APInt &RHS) const
Unsigned less than comparison.
Definition APInt.h:1115
unsigned countr_zero() const
Count the number of trailing zero bits.
Definition APInt.h:1659
unsigned countl_zero() const
The APInt version of std::countl_zero.
Definition APInt.h:1618
static LLVM_ABI APInt getSplat(unsigned NewLen, const APInt &V)
Return a value containing V broadcasted over NewLen bits.
Definition APInt.cpp:648
unsigned logBase2() const
Definition APInt.h:1781
uint64_t getLimitedValue(uint64_t Limit=UINT64_MAX) const
If this value is smaller than the specified limit, return it, otherwise return the limit value.
Definition APInt.h:471
bool isSubsetOf(const APInt &RHS) const
This operation checks that all bits set in this APInt are also set in RHS.
Definition APInt.h:1261
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
Definition APInt.h:436
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
Definition APInt.h:302
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
Definition APInt.h:292
bool isOne() const
Determine if this is a value of 1.
Definition APInt.h:385
static APInt getOneBitSet(unsigned numBits, unsigned BitNo)
Return an APInt with exactly one bit set in the result.
Definition APInt.h:235
int64_t getSExtValue() const
Get sign extended value.
Definition APInt.h:1582
void lshrInPlace(unsigned ShiftAmt)
Logical right-shift this APInt by ShiftAmt in place.
Definition APInt.h:860
APInt lshr(unsigned shiftAmt) const
Logical right-shift function.
Definition APInt.h:853
unsigned countr_one() const
Count the number of trailing one bits.
Definition APInt.h:1676
bool uge(const APInt &RHS) const
Unsigned greater or equal comparison.
Definition APInt.h:1225
An arbitrary precision integer that knows its signedness.
Definition APSInt.h:24
const ARMBaseRegisterInfo & getRegisterInfo() const
const uint32_t * getSjLjDispatchPreservedMask(const MachineFunction &MF) const
const MCPhysReg * getCalleeSavedRegs(const MachineFunction *MF) const override
Code Generation virtual methods...
Register getFrameRegister(const MachineFunction &MF) const override
const uint32_t * getCallPreservedMask(const MachineFunction &MF, CallingConv::ID) const override
const uint32_t * getTLSCallPreservedMask(const MachineFunction &MF) const
const uint32_t * getThisReturnPreservedMask(const MachineFunction &MF, CallingConv::ID) const
getThisReturnPreservedMask - Returns a call preserved mask specific to the case that 'returned' is on...
static ARMConstantPoolConstant * Create(const Constant *C, unsigned ID)
static ARMConstantPoolMBB * Create(LLVMContext &C, const MachineBasicBlock *mbb, unsigned ID, unsigned char PCAdj)
static ARMConstantPoolSymbol * Create(LLVMContext &C, StringRef s, unsigned ID, unsigned char PCAdj, ARMCP::ARMCPModifier Modifier=ARMCP::no_modifier, bool AddCurrentAddress=false)
ARMConstantPoolValue - ARM specific constantpool value.
ARMFunctionInfo - This class is derived from MachineFunctionInfo and contains private ARM-specific in...
SmallPtrSet< const GlobalVariable *, 2 > & getGlobalsPromotedToConstantPool()
void setArgumentStackToRestore(unsigned v)
void setArgRegsSaveSize(unsigned s)
void setReturnRegsCount(unsigned s)
unsigned getArgRegsSaveSize() const
void markGlobalAsPromotedToConstantPool(const GlobalVariable *GV)
Indicate to the backend that GV has had its storage changed to inside a constant pool.
void setArgumentStackSize(unsigned size)
unsigned getArgumentStackSize() const
const Triple & getTargetTriple() const
const ARMBaseInstrInfo * getInstrInfo() const override
bool isThumb1Only() const
bool useFPVFMx() const
bool isThumb2() const
bool hasBaseDSP() const
const ARMTargetLowering * getTargetLowering() const override
const ARMBaseRegisterInfo * getRegisterInfo() const override
bool hasVFP2Base() const
bool useFPVFMx64() const
bool isLittle() const
bool useFPVFMx16() const
bool isMClass() const
bool useMulOps() const
bool shouldFoldSelectWithIdentityConstant(unsigned BinOpcode, EVT VT, unsigned SelectOpcode, SDValue X, SDValue Y) const override
Return true if pulling a binary operation into a select with an identity constant is profitable.
bool isReadOnly(const GlobalValue *GV) const
unsigned getMaxSupportedInterleaveFactor() const override
Get the maximum supported factor for interleaved memory accesses.
TargetLoweringBase::AtomicExpansionKind shouldExpandAtomicLoadInIR(LoadInst *LI) const override
Returns how the given (atomic) load should be expanded by the IR-level AtomicExpand pass.
unsigned getNumInterleavedAccesses(VectorType *VecTy, const DataLayout &DL) const
Returns the number of interleaved accesses that will be generated when lowering accesses of the given...
bool shouldInsertFencesForAtomic(const Instruction *I) const override
Whether AtomicExpandPass should automatically insert fences and reduce ordering for this atomic.
Align getABIAlignmentForCallingConv(Type *ArgTy, const DataLayout &DL) const override
Return the correct alignment for the current calling convention.
bool isDesirableToCommuteWithShift(const SDNode *N, CombineLevel Level) const override
Return true if it is profitable to move this shift by a constant amount through its operand,...
ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const override
Examine constraint string and operand type and determine a weight value.
bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty, unsigned AS, Instruction *I=nullptr) const override
isLegalAddressingMode - Return true if the addressing mode represented by AM is legal for this target...
const ARMSubtarget * getSubtarget() const
bool isLegalT2ScaledAddressingMode(const AddrMode &AM, EVT VT) const
bool isLegalT1ScaledAddressingMode(const AddrMode &AM, EVT VT) const
Returns true if the addressing mode representing by AM is legal for the Thumb1 target,...
bool getPreIndexedAddressParts(SDNode *N, SDValue &Base, SDValue &Offset, ISD::MemIndexedMode &AM, SelectionDAG &DAG) const override
getPreIndexedAddressParts - returns true by value, base pointer and offset pointer and addressing mod...
MachineInstr * EmitKCFICheck(MachineBasicBlock &MBB, MachineBasicBlock::instr_iterator &MBBI, const TargetInstrInfo *TII) const override
bool shouldAlignPointerArgs(CallInst *CI, unsigned &MinSize, Align &PrefAlign) const override
Return true if the pointer arguments to CI should be aligned by aligning the object whose address is ...
void getTgtMemIntrinsic(SmallVectorImpl< IntrinsicInfo > &Infos, const CallBase &I, MachineFunction &MF, unsigned Intrinsic) const override
getTgtMemIntrinsic - Represent NEON load and store intrinsics as MemIntrinsicNodes.
void ReplaceNodeResults(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG) const override
ReplaceNodeResults - Replace the results of node with an illegal result type with new values built ou...
void emitAtomicCmpXchgNoStoreLLBalance(IRBuilderBase &Builder) const override
bool isMulAddWithConstProfitable(SDValue AddNode, SDValue ConstNode) const override
Return true if it may be profitable to transform (mul (add x, c1), c2) -> (add (mul x,...
bool isLegalAddImmediate(int64_t Imm) const override
isLegalAddImmediate - Return true if the specified immediate is legal add immediate,...
EVT getOptimalMemOpType(LLVMContext &Context, const MemOp &Op, const AttributeList &FuncAttributes) const override
Returns the target specific optimal type for load and store operations as a result of memset,...
Instruction * emitTrailingFence(IRBuilderBase &Builder, Instruction *Inst, AtomicOrdering Ord) const override
bool isFNegFree(EVT VT) const override
Return true if an fneg operation is free to the point where it is never worthwhile to replace it with...
void finalizeLowering(MachineFunction &MF) const override
Execute target specific actions to finalize target lowering.
SDValue PerformMVETruncCombine(SDNode *N, DAGCombinerInfo &DCI) const
bool isFPImmLegal(const APFloat &Imm, EVT VT, bool ForCodeSize=false) const override
isFPImmLegal - Returns true if the target can instruction select the specified FP immediate natively.
ConstraintType getConstraintType(StringRef Constraint) const override
getConstraintType - Given a constraint letter, return the type of constraint it is for this target.
bool preferIncOfAddToSubOfNot(EVT VT) const override
These two forms are equivalent: sub y, (xor x, -1) add (add x, 1), y The variant with two add's is IR...
void computeKnownBitsForTargetNode(const SDValue Op, KnownBits &Known, const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth) const override
Determine which of the bits specified in Mask are known to be either zero or one and return them in t...
TargetLoweringBase::AtomicExpansionKind shouldExpandAtomicStoreInIR(StoreInst *SI) const override
Returns how the given (atomic) store should be expanded by the IR-level AtomicExpand pass into.
SDValue PerformIntrinsicCombine(SDNode *N, DAGCombinerInfo &DCI) const
PerformIntrinsicCombine - ARM-specific DAG combining for intrinsics.
bool shouldFoldConstantShiftPairToMask(const SDNode *N) const override
Return true if it is profitable to fold a pair of shifts into a mask.
bool isDesirableToCommuteXorWithShift(const SDNode *N) const override
Return true if it is profitable to combine an XOR of a logical shift to create a logical shift of NOT...
SDValue PerformCMOVCombine(SDNode *N, SelectionDAG &DAG) const
PerformCMOVCombine - Target-specific DAG combining for ARMISD::CMOV.
TargetLoweringBase::AtomicExpansionKind shouldExpandAtomicRMWInIR(const AtomicRMWInst *AI) const override
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
Value * createComplexDeinterleavingIR(IRBuilderBase &B, ComplexDeinterleavingOperation OperationType, ComplexDeinterleavingRotation Rotation, Value *InputA, Value *InputB, Value *Accumulator=nullptr) const override
Create the IR node for the given complex deinterleaving operation.
bool isComplexDeinterleavingSupported() const override
Does this target support complex deinterleaving.
SDValue PerformMVEExtCombine(SDNode *N, DAGCombinerInfo &DCI) const
FastISel * createFastISel(FunctionLoweringInfo &funcInfo, const TargetLibraryInfo *libInfo, const LibcallLoweringInfo *libcallLowering) const override
createFastISel - This method returns a target specific FastISel object, or null if the target does no...
void insertSSPDeclarations(Module &M, const LibcallLoweringInfo &Libcalls) const override
Inserts necessary declarations for SSP (stack protection) purpose.
bool SimplifyDemandedBitsForTargetNode(SDValue Op, const APInt &OriginalDemandedBits, const APInt &OriginalDemandedElts, KnownBits &Known, TargetLoweringOpt &TLO, unsigned Depth) const override
Attempt to simplify any target nodes based on the demanded bits/elts, returning true on success.
EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, EVT VT) const override
getSetCCResultType - Return the value type to use for ISD::SETCC.
MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *MBB) const override
This method should be implemented by targets that mark instructions with the 'usesCustomInserter' fla...
Value * emitStoreConditional(IRBuilderBase &Builder, Value *Val, Value *Addr, AtomicOrdering Ord) const override
Perform a store-conditional operation to Addr.
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override
This callback is invoked for operations that are unsupported by the target, which are registered to u...
CCAssignFn * CCAssignFnForReturn(CallingConv::ID CC, bool isVarArg) const
void AdjustInstrPostInstrSelection(MachineInstr &MI, SDNode *Node) const override
This method should be implemented by targets that mark instructions with the 'hasPostISelHook' flag.
bool isTruncateFree(Type *SrcTy, Type *DstTy) const override
Return true if it's free to truncate a value of type FromTy to type ToTy.
bool isShuffleMaskLegal(ArrayRef< int > M, EVT VT) const override
isShuffleMaskLegal - Targets can use this to indicate that they only support some VECTOR_SHUFFLE oper...
Register getExceptionPointerRegister(ExceptionHandling EH, const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception address on entry to an ...
TargetLoweringBase::AtomicExpansionKind shouldExpandAtomicCmpXchgInIR(const AtomicCmpXchgInst *AI) const override
Returns how the given atomic cmpxchg should be expanded by the IR-level AtomicExpand pass.
bool shouldConvertConstantLoadToIntImm(const APInt &Imm, Type *Ty) const override
Returns true if it is beneficial to convert a load of a constant to just the constant itself.
bool lowerInterleavedStore(Instruction *Store, Value *Mask, ShuffleVectorInst *SVI, unsigned Factor, const APInt &GapMask) const override
Lower an interleaved store into a vstN intrinsic.
const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const override
getRegClassFor - Return the register class that should be used for the specified value type.
bool useLoadStackGuardNode(const Module &M) const override
If this function returns true, SelectionDAGBuilder emits a LOAD_STACK_GUARD node when it is lowering ...
bool lowerInterleavedLoad(Instruction *Load, Value *Mask, ArrayRef< ShuffleVectorInst * > Shuffles, ArrayRef< unsigned > Indices, unsigned Factor, const APInt &GapMask) const override
Lower an interleaved load into a vldN intrinsic.
std::pair< const TargetRegisterClass *, uint8_t > findRepresentativeClass(const TargetRegisterInfo *TRI, MVT VT) const override
Return the largest legal super-reg register class of the register class for the specified type and it...
bool preferSelectsOverBooleanArithmetic(EVT VT) const override
Should we prefer selects to doing arithmetic on boolean types.
bool isZExtFree(SDValue Val, EVT VT2) const override
Return true if zero-extending the specific node Val to type VT2 is free (either because it's implicit...
bool isCheapToSpeculateCttz(Type *Ty) const override
Return true if it is cheap to speculate a call to intrinsic cttz.
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override
This method will be invoked for all target nodes and for any target-independent nodes that the target...
bool isCheapToSpeculateCtlz(Type *Ty) const override
Return true if it is cheap to speculate a call to intrinsic ctlz.
bool targetShrinkDemandedConstant(SDValue Op, const APInt &DemandedBits, const APInt &DemandedElts, TargetLoweringOpt &TLO) const override
bool hasAndNot(SDValue Y) const override
Return true if the target has a bitwise and-not operation: X = ~A & B This can be used to simplify se...
Register getExceptionSelectorRegister(ExceptionHandling EH, const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception typeid on entry to a la...
ExtractSubvectorCost getExtractSubvectorCost(EVT ResVT, EVT SrcVT, unsigned Index) const override
Return the cost of EXTRACT_SUBVECTOR for this result type with this index.
CallingConv::ID getEffectiveCallingConv(CallingConv::ID CC, bool isVarArg) const
getEffectiveCallingConv - Get the effective calling convention, taking into account presence of float...
ARMTargetLowering(const TargetMachine &TM, const ARMSubtarget &STI)
bool isComplexDeinterleavingOperationSupported(ComplexDeinterleavingOperation Operation, Type *Ty) const override
Does this target support complex deinterleaving with the given operation and type.
bool supportKCFIBundles() const override
Return true if the target supports kcfi operand bundles.
SDValue PerformBRCONDCombine(SDNode *N, SelectionDAG &DAG) const
PerformBRCONDCombine - Target-specific DAG combining for ARMISD::BRCOND.
Type * shouldConvertSplatType(ShuffleVectorInst *SVI) const override
Given a shuffle vector SVI representing a vector splat, return a new scalar type of size equal to SVI...
Value * emitLoadLinked(IRBuilderBase &Builder, Type *ValueTy, Value *Addr, AtomicOrdering Ord) const override
Perform a load-linked operation on Addr, returning a "Value *" with the corresponding pointee type.
Instruction * makeDMB(IRBuilderBase &Builder, ARM_MB::MemBOpt Domain) const
bool isLegalICmpImmediate(int64_t Imm) const override
isLegalICmpImmediate - Return true if the specified immediate is legal icmp immediate,...
const char * LowerXConstraint(EVT ConstraintVT) const override
Try to replace an X constraint, which matches anything, with another that has more specific requireme...
unsigned getJumpTableEncoding() const override
Return the entry encoding for a jump table in the current function.
bool isDesirableToTransformToIntegerOp(unsigned Opc, EVT VT) const override
Return true if it is profitable for dag combiner to transform a floating point op of specified opcode...
CCAssignFn * CCAssignFnForCall(CallingConv::ID CC, bool isVarArg) const
bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AddrSpace, Align Alignment, MachineMemOperand::Flags Flags, unsigned *Fast) const override
allowsMisalignedMemoryAccesses - Returns true if the target allows unaligned memory accesses of the s...
bool isLegalInterleavedAccessType(unsigned Factor, FixedVectorType *VecTy, Align Alignment, const DataLayout &DL) const
Returns true if VecTy is a legal interleaved access type.
bool isVectorLoadExtDesirable(SDValue ExtVal) const override
Return true if folding a vector load into ExtVal (a sign, zero, or any extend node) is profitable.
bool canCombineStoreAndExtract(Type *VectorTy, Value *Idx, unsigned &Cost) const override
Return true if the target can combine store(extractelement VectorTy,Idx).
bool useSoftFloat() const override
bool alignLoopsWithOptSize() const override
Should loops be aligned even when the function is marked OptSize (but not MinSize).
SDValue PerformCMOVToBFICombine(SDNode *N, SelectionDAG &DAG) const
bool allowTruncateForTailCall(Type *Ty1, Type *Ty2) const override
Return true if a truncation from FromTy to ToTy is permitted when deciding whether a call is in tail ...
void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const override
LowerAsmOperandForConstraint - Lower the specified operand into the Ops vector.
bool hasAndNotCompare(SDValue V) const override
Return true if the target should transform: (X & Y) == Y ---> (~X & Y) == 0 (X & Y) !...
std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const override
Given a physical register constraint (e.g.
bool shouldConvertFpToSat(unsigned Op, EVT FPVT, EVT VT) const override
Should we generate fp_to_si_sat and fp_to_ui_sat from type FPVT to type VT.
bool functionArgumentNeedsConsecutiveRegisters(Type *Ty, CallingConv::ID CallConv, bool isVarArg, const DataLayout &DL) const override
Returns true if an argument of type Ty needs to be passed in a contiguous block of registers in calli...
bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override
Return true if folding a constant offset with the given GlobalAddress is legal.
const ARMBaseTargetMachine & getTM() const
bool isMaskAndCmp0FoldingBeneficial(const Instruction &AndI) const override
Return if the target supports combining a chain like:
ShiftLegalizationStrategy preferredShiftLegalizationStrategy(SelectionDAG &DAG, SDNode *N, unsigned ExpansionFactor) const override
bool getPostIndexedAddressParts(SDNode *N, SDNode *Op, SDValue &Base, SDValue &Offset, ISD::MemIndexedMode &AM, SelectionDAG &DAG) const override
getPostIndexedAddressParts - returns true by value, base pointer and offset pointer and addressing mo...
Instruction * emitLeadingFence(IRBuilderBase &Builder, Instruction *Inst, AtomicOrdering Ord) const override
Inserts in the IR a target-specific intrinsic specifying a fence.
bool canCreateUndefOrPoisonForTargetNode(SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG, UndefPoisonKind Kind, bool ConsiderFlags, unsigned Depth) const override
Return true if Op can create undef or poison from non-undef & non-poison operands.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
size_t size() const
Get the array size.
Definition ArrayRef.h:141
bool empty() const
Check if the array is empty.
Definition ArrayRef.h:136
An instruction that atomically checks whether a specified value is in a memory location,...
an instruction that atomically reads a memory location, combines it with another value,...
bool isFloatingPointOperation() const
static LLVM_ABI Attribute get(LLVMContext &Context, AttrKind Kind, uint64_t Val=0)
Return a uniquified Attribute object.
static LLVM_ABI BaseIndexOffset match(const SDNode *N, const SelectionDAG &DAG)
Parses tree in N for base, index, offset addresses.
LLVM Basic Block Representation.
Definition BasicBlock.h:62
The address of a basic block.
Definition Constants.h:1088
static constexpr BranchProbability getZero()
A "pseudo-class" with methods for operating on BUILD_VECTORs.
LLVM_ABI bool isConstantSplat(APInt &SplatValue, APInt &SplatUndef, unsigned &SplatBitSize, bool &HasAnyUndefs, unsigned MinSplatBits=0, bool isBigEndian=false) const
Check if this is a constant splat, and if so, find the smallest element size that splats the vector.
LLVM_ABI int32_t getConstantFPSplatPow2ToLog2Int(BitVector *UndefElements, uint32_t BitWidth) const
If this is a constant FP splat and the splatted constant FP is an exact power or 2,...
CCState - This class holds information needed while lowering arguments and return values.
void getInRegsParamInfo(unsigned InRegsParamRecordIndex, unsigned &BeginReg, unsigned &EndReg) const
unsigned getFirstUnallocated(ArrayRef< MCPhysReg > Regs) const
getFirstUnallocated - Return the index of the first unallocated register in the set,...
static LLVM_ABI bool resultsCompatible(CallingConv::ID CalleeCC, CallingConv::ID CallerCC, MachineFunction &MF, LLVMContext &C, const SmallVectorImpl< ISD::InputArg > &Ins, CCAssignFn CalleeFn, CCAssignFn CallerFn)
Returns true if the results of the two calling conventions are compatible.
MCRegister AllocateReg(MCPhysReg Reg)
AllocateReg - Attempt to allocate one register.
LLVM_ABI bool CheckReturn(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)
CheckReturn - Analyze the return values of a function, returning true if the return can be performed ...
LLVM_ABI void AnalyzeReturn(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)
AnalyzeReturn - Analyze the returned values of a return, incorporating info about the result values i...
unsigned getInRegsParamsProcessed() const
uint64_t getStackSize() const
Returns the size of the currently allocated portion of the stack.
void addInRegsParamInfo(unsigned RegBegin, unsigned RegEnd)
LLVM_ABI void AnalyzeFormalArguments(const SmallVectorImpl< ISD::InputArg > &Ins, CCAssignFn Fn)
AnalyzeFormalArguments - Analyze an array of argument values, incorporating info about the formals in...
unsigned getInRegsParamsCount() const
CCValAssign - Represent assignment of one arg/retval to a location.
Register getLocReg() const
LocInfo getLocInfo() const
bool needsCustom() const
int64_t getLocMemOffset() const
unsigned getValNo() const
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
LLVM_ABI bool isMustTailCall() const
Tests if this call site must be tail call optimized.
AttributeList getAttributes() const
Return the attributes for this call.
void addParamAttr(unsigned ArgNo, Attribute::AttrKind Kind)
Adds the attribute to the indicated argument.
This class represents a function call, abstracting a target machine's calling convention.
bool isTailCall() const
static Constant * get(LLVMContext &Context, ArrayRef< ElementTy > Elts)
get() constructor - Return a constant with array type with an element count and element type matching...
Definition Constants.h:878
const APFloat & getValueAPF() const
ConstantFP - Floating Point Values [float, double].
Definition Constants.h:420
This is the shared class of boolean and integer constants.
Definition Constants.h:87
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
Definition Constants.h:168
MachineConstantPoolValue * getMachineCPVal() const
const Constant * getConstVal() const
LLVM_ABI Type * getType() const
uint64_t getZExtValue() const
const APInt & getAPIntValue() const
int64_t getSExtValue() const
This is an important base class in LLVM.
Definition Constant.h:43
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
bool isLittleEndian() const
Layout endianness...
Definition DataLayout.h:217
bool isBigEndian() const
Definition DataLayout.h:218
MaybeAlign getStackAlignment() const
Returns the natural stack alignment, or MaybeAlign() if one wasn't specified.
Definition DataLayout.h:250
LLVM_ABI TypeSize getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
StringRef getInternalSymbolPrefix() const
Definition DataLayout.h:308
LLVM_ABI Align getPreferredAlign(const GlobalVariable *GV) const
Returns the preferred alignment of the specified global.
LLVM_ABI Align getPrefTypeAlign(Type *Ty) const
Returns the preferred stack/global alignment for the specified type.
A debug info location.
Definition DebugLoc.h:126
iterator find(const_arg_type_t< KeyT > Val)
Definition DenseMap.h:258
unsigned size() const
Definition DenseMap.h:207
bool empty() const
Definition DenseMap.h:206
iterator begin()
Definition DenseMap.h:172
iterator end()
Definition DenseMap.h:176
This is a fast-path instruction selection class that generates poor code and doesn't support illegal ...
Definition FastISel.h:67
Class to represent fixed width SIMD vectors.
unsigned getNumElements() const
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
Definition Type.cpp:843
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
FunctionLoweringInfo - This contains information that is global to a function that is used when lower...
Type * getParamType(unsigned i) const
Parameter type accessors.
FunctionType * getFunctionType() const
Returns the FunctionType for me.
Definition Function.h:212
bool hasMinSize() const
Optimize this function for minimum size (-Oz).
Definition Function.h:696
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
Definition Function.h:273
arg_iterator arg_begin()
Definition Function.h:853
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Definition Function.cpp:356
bool hasStructRetAttr() const
Determine if the function returns a structure through first or second pointer argument.
Definition Function.h:673
const Argument * const_arg_iterator
Definition Function.h:74
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
Definition Function.h:230
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition Function.cpp:730
const GlobalValue * getGlobal() const
bool isDSOLocal() const
bool hasExternalWeakLinkage() const
bool hasDLLImportStorageClass() const
Module * getParent()
Get the module that this global value is contained inside of...
bool isStrongDefinitionForLinker() const
Returns true if this global's definition will be the one chosen by the linker.
@ InternalLinkage
Rename collisions when linking (static functions).
Definition GlobalValue.h:60
Common base class shared among various IRBuilders.
Definition IRBuilder.h:114
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2903
LLVM_ABI bool hasAtomicStore() const LLVM_READONLY
Return true if this atomic instruction stores to memory.
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:68
LLVM_ABI void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
bool isIndexed() const
Return true if this is a pre/post inc/dec load/store.
Tracks which library functions to use for a particular subtarget or function.
CallingConv::ID getLibcallImplCallingConv(RTLIB::LibcallImpl Call) const
Get the CallingConv that should be used for the specified libcall.
RTLIB::LibcallImpl getLibcallImpl(RTLIB::Libcall Call) const
Return the lowering's selection of implementation call for Call.
An instruction for reading from memory.
This class is used to represent ISD::LOAD nodes.
const SDValue & getBasePtr() const
Describe properties that are true of each instruction in the target description file.
Machine Value Type.
static MVT getFloatingPointVT(unsigned BitWidth)
static auto integer_fixedlen_vector_valuetypes()
SimpleValueType SimpleTy
uint64_t getScalarSizeInBits() const
unsigned getVectorNumElements() const
bool isInteger() const
Return true if this is an integer or a vector integer type.
static LLVM_ABI MVT getVT(Type *Ty, bool HandleUnknown=false)
Return the value type corresponding to the specified type.
static auto integer_valuetypes()
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
static auto fixedlen_vector_valuetypes()
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
bool isScalarInteger() const
Return true if this is an integer, not including vectors.
static MVT getVectorVT(MVT VT, unsigned NumElements)
MVT getVectorElementType() const
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
static MVT getIntegerVT(unsigned BitWidth)
static auto fp_valuetypes()
bool is64BitVector() const
Return true if this is a 64-bit vector type.
LLVM_ABI void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
bool isEHPad() const
Returns true if the block is a landing pad.
LLVM_ABI MachineBasicBlock * getFallThrough(bool JumpToFallThrough=true)
Return the fallthrough block if the block can implicitly transfer control to the block after it by fa...
void setCallFrameSize(unsigned N)
Set the call frame size on entry to this basic block.
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
LLVM_ABI bool canFallThrough()
Return true if the block can implicitly transfer control to the block after it by falling off the end...
LLVM_ABI void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
Instructions::iterator instr_iterator
MachineInstrBundleIterator< MachineInstr, true > reverse_iterator
LLVM_ABI MachineBasicBlock * splitAt(MachineInstr &SplitInst, bool UpdateLiveIns=true, LiveIntervals *LIS=nullptr)
Split a basic block into 2 pieces at SplitPoint.
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
LLVM_ABI instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
iterator_range< succ_iterator > successors()
iterator_range< pred_iterator > predecessors()
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
MachineInstrBundleIterator< MachineInstr > iterator
LLVM_ABI void moveAfter(MachineBasicBlock *NewBefore)
LLVM_ABI bool isLiveIn(MCRegister Reg, LaneBitmask LaneMask=LaneBitmask::getAll()) const
Return true if the specified register is in the live in set.
void setIsEHPad(bool V=true)
Indicates the block is a landing pad.
The MachineConstantPool class keeps track of constants referenced by a function which must be spilled...
LLVM_ABI unsigned getConstantPoolIndex(const Constant *C, Align Alignment)
getConstantPoolIndex - Create a new entry in the constant pool or return an existing one.
LLVM_ABI int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
LLVM_ABI void computeMaxCallFrameSize(MachineFunction &MF, std::vector< MachineBasicBlock::iterator > *FrameSDOps=nullptr)
Computes the maximum size of a callframe.
void setFrameAddressIsTaken(bool T)
void setHasTailCall(bool V=true)
void setReturnAddressIsTaken(bool s)
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
bool hasVAStart() const
Returns true if the function calls the llvm.va_start intrinsic.
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
bool isFixedObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a fixed stack object.
int getFunctionContextIndex() const
Return the index for the function context object.
Properties which a MachineFunction may have at a given point in time.
unsigned getFunctionNumber() const
getFunctionNumber - Return a unique ID for the current function.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
void push_back(MachineBasicBlock *MBB)
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Function & getFunction()
Return the LLVM function that this machine code represents.
BasicBlockListType::iterator iterator
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
MachineConstantPool * getConstantPool()
getConstantPool - Return the constant pool object for the current function.
const MachineFunctionProperties & getProperties() const
Get the function properties.
Register addLiveIn(MCRegister PReg, const TargetRegisterClass *RC)
addLiveIn - Add the specified physical register as a live-in value and create a corresponding virtual...
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags F, LLT MemTy, Align BaseAlignment, const MMOMetadata &Metadata=MMOMetadata(), SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineInstr - Allocate a new MachineInstr.
void insert(iterator MBBI, MachineBasicBlock *MBB)
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
const MachineInstrBuilder & addExternalSymbol(const char *FnName, unsigned TargetFlags=0) const
const MachineInstrBuilder & addUse(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addConstantPoolIndex(unsigned Idx, int Offset=0, unsigned TargetFlags=0) const
const MachineInstrBuilder & addRegMask(const uint32_t *Mask) const
const MachineInstrBuilder & addJumpTableIndex(unsigned Idx, unsigned TargetFlags=0) const
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & addDef(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register definition operand.
const MachineInstrBuilder & cloneMemRefs(const MachineInstr &OtherMI) const
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly.
Representation of each machine instruction.
bool readsRegister(Register Reg, const TargetRegisterInfo *TRI) const
Return true if the MachineInstr reads the specified register.
bool definesRegister(Register Reg, const TargetRegisterInfo *TRI) const
Return true if the MachineInstr fully defines the specified register.
MachineOperand * mop_iterator
iterator/begin/end - Iterate over all operands of a machine instruction.
const MachineOperand & getOperand(unsigned i) const
LLVM_ABI unsigned createJumpTableIndex(const std::vector< MachineBasicBlock * > &DestBBs)
createJumpTableIndex - Create a new jump table.
@ EK_Inline
EK_Inline - Jump table entries are emitted inline at their point of use.
@ EK_BlockAddress
EK_BlockAddress - Each entry is a plain address of block, e.g.: .word LBB123.
A description of a memory reference used in the backend.
Flags
Flags values. These may be or'd together.
@ MOVolatile
The memory access is volatile.
@ MODereferenceable
The memory access is dereferenceable (i.e., doesn't trap).
@ MOLoad
The memory access reads data.
@ MONonTemporal
The memory access is non-temporal.
@ MOInvariant
The memory access always returns the same value (or traps).
@ MOStore
The memory access writes data.
MachineOperand class - Representation of each machine instruction operand.
LLVM_ABI void setIsRenamable(bool Val=true)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
LLVM_ABI void setReg(Register Reg)
Change the register this operand corresponds to.
static MachineOperand CreateImm(int64_t Val)
Register getReg() const
getReg - Returns the register number.
LLVM_ABI void setIsDef(bool Val=true)
Change a def to a use, or a use to a def.
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
This class is used to represent an MLOAD node.
This class is used to represent an MSTORE node.
This SDNode is used for target intrinsics that touch memory and need an associated MachineMemOperand.
This is an abstract virtual class for memory operations.
Align getAlign() const
bool isSimple() const
Returns true if the memory operation is neither atomic or volatile.
MachineMemOperand * getMemOperand() const
Return the unique MachineMemOperand object describing the memory reference performed by operation.
const SDValue & getChain() const
EVT getMemoryVT() const
Return the type of the in-memory value.
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:68
static PointerType * getUnqual(LLVMContext &C)
This constructs an opaque pointer to an object in the default address space (address space zero).
Wrapper class representing virtual and physical registers.
Definition Register.h:20
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
const DebugLoc & getDebugLoc() const
Represents one node in the SelectionDAG.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
bool hasOneUse() const
Return true if there is exactly one use of this node.
LLVM_ABI bool isOnlyUserOf(const SDNode *N) const
Return true if this node is the only use of N.
iterator_range< use_iterator > uses()
SDNodeFlags getFlags() const
static bool hasPredecessorHelper(const SDNode *N, SmallPtrSetImpl< const SDNode * > &Visited, SmallVectorImpl< const SDNode * > &Worklist, unsigned int MaxSteps=0, bool TopologicalPrune=false)
Returns true if N is a predecessor of any node in Worklist.
uint64_t getAsZExtVal() const
Helper method returns the zero-extended integer value of a ConstantSDNode.
bool use_empty() const
Return true if there are no uses of this node.
unsigned getNumValues() const
Return the number of values defined/returned by this operator.
unsigned getNumOperands() const
Return the number of values used by this operation.
const SDValue & getOperand(unsigned Num) const
uint64_t getConstantOperandVal(unsigned Num) const
Helper method returns the integer value of a ConstantSDNode operand.
const APInt & getConstantOperandAPInt(unsigned Num) const
Helper method returns the APInt of a ConstantSDNode operand.
bool isPredecessorOf(const SDNode *N) const
Return true if this node is a predecessor of N.
LLVM_ABI bool hasAnyUseOfValue(unsigned Value) const
Return true if there are any use of the indicated value.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
void setCFIType(uint32_t Type)
bool isUndef() const
Returns true if the node type is UNDEF or POISON.
iterator_range< user_iterator > users()
void setFlags(SDNodeFlags NewFlags)
user_iterator user_begin() const
Provide iteration support to walk over all users of an SDNode.
Represents a use of a SDNode.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
bool isUndef() const
SDNode * getNode() const
get the SDNode which holds the desired result
bool hasOneUse() const
Return true if there is exactly one node using value ResNo of Node, in exactly one operand.
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
const SDValue & getOperand(unsigned i) const
const APInt & getConstantOperandAPInt(unsigned i) const
uint64_t getScalarValueSizeInBits() const
unsigned getResNo() const
get the index which selects a specific result in the SDNode
uint64_t getConstantOperandVal(unsigned i) const
unsigned getOpcode() const
unsigned getNumOperands() const
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)
LLVM_ABI SDValue getStackArgumentTokenFactor(SDValue Chain)
Compute a TokenFactor to force all the incoming stack arguments to be loaded from the stack.
const TargetSubtargetInfo & getSubtarget() const
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, Register Reg, SDValue N)
LLVM_ABI SDValue getMergeValues(ArrayRef< SDValue > Ops, const SDLoc &dl)
Create a MERGE_VALUES node from the given operands.
LLVM_ABI SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
LLVM_ABI SDValue getSplatValue(SDValue V, bool LegalTypes=false)
If V is a splat vector, return its scalar source operand by extracting that element from the source v...
LLVM_ABI SDValue getAllOnesConstant(const SDLoc &DL, EVT VT, bool IsTarget=false, bool IsOpaque=false)
LLVM_ABI MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s),...
LLVM_ABI SDNode * getNodeIfExists(unsigned Opcode, SDVTList VTList, ArrayRef< SDValue > Ops, const SDNodeFlags Flags, bool AllowCommute=false)
Get the specified node if it's already available, or else return NULL.
LLVM_ABI SDValue UnrollVectorOp(SDNode *N, unsigned ResNE=0)
Utility function used by legalize and lowering to "unroll" a vector operation by splitting out the sc...
LLVM_ABI bool haveNoCommonBitsSet(SDValue A, SDValue B) const
Return true if A and B have no common bits set.
LLVM_ABI SDValue getRegister(Register Reg, EVT VT)
LLVM_ABI SDValue getMemIntrinsicNode(unsigned Opcode, const SDLoc &dl, SDVTList VTList, ArrayRef< SDValue > Ops, EVT MemVT, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags Flags=MachineMemOperand::MOLoad|MachineMemOperand::MOStore, LocationSize Size=LocationSize::precise(0), const AAMDNodes &AAInfo=AAMDNodes())
Creates a MemIntrinsicNode that may produce a result and takes a list of operands.
void addNoMergeSiteInfo(const SDNode *Node, bool NoMerge)
Set NoMergeSiteInfo to be associated with Node if NoMerge is true.
std::pair< SDValue, SDValue > SplitVectorOperand(const SDNode *N, unsigned OpNo)
Split the node's operand with EXTRACT_SUBVECTOR and return the low/high part.
LLVM_ABI SDValue getNOT(const SDLoc &DL, SDValue Val, EVT VT)
Create a bitwise NOT operation as (XOR Val, -1).
const TargetLowering & getTargetLoweringInfo() const
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)
SDValue getUNDEF(EVT VT)
Return an UNDEF node. UNDEF does not have a useful SDLoc.
SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2, SDValue InGlue, const SDLoc &DL)
Return a new CALLSEQ_END node, which always must have a glue result (to ensure it's not CSE'd).
SDValue getBuildVector(EVT VT, const SDLoc &DL, ArrayRef< SDValue > Ops)
Return an ISD::BUILD_VECTOR node.
LLVM_ABI SDValue getTruncStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, SDValue Offset, MachinePointerInfo PtrInfo, EVT SVT, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const MMOMetadata &Metadata=MMOMetadata())
LLVM_ABI SDValue getBitcast(EVT VT, SDValue V)
Return a bitcast using the SDLoc of the value operand, and casting to the provided type.
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, Register Reg, EVT VT)
LLVM_ABI SDValue getNegative(SDValue Val, const SDLoc &DL, EVT VT)
Create negative operation as (SUB 0, Val).
LLVM_ABI void setNodeMemRefs(MachineSDNode *N, ArrayRef< MachineMemOperand * > NewMemRefs)
Mutate the specified machine node's memory references to the provided list.
LLVM_ABI SDValue getZeroExtendInReg(SDValue Op, const SDLoc &DL, EVT VT)
Return the expression required to zero extend the Op value assuming it was the smaller SrcTy value.
const DataLayout & getDataLayout() const
LLVM_ABI SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const MMOMetadata &Metadata=MMOMetadata())
Helper function to build ISD::STORE nodes.
LLVM_ABI SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
SDValue getSignedTargetConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
LLVM_ABI void ReplaceAllUsesWith(SDValue From, SDValue To)
Modify anything using 'From' to use 'To' instead.
LLVM_ABI SDValue getExtLoad(ISD::LoadExtType ExtType, const SDLoc &dl, EVT VT, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, EVT MemVT, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const MMOMetadata &Metadata=MMOMetadata())
LLVM_ABI std::pair< SDValue, SDValue > SplitVector(const SDValue &N, const SDLoc &DL, const EVT &LoVT, const EVT &HiVT)
Split the vector with EXTRACT_SUBVECTOR using the provided VTs and return the low/high part.
LLVM_ABI SDValue getSignedConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
LLVM_ABI MaybeAlign InferPtrAlign(SDValue Ptr) const
Infer alignment of a load / store address.
SDValue getCALLSEQ_START(SDValue Chain, uint64_t InSize, uint64_t OutSize, const SDLoc &DL)
Return a new CALLSEQ_START node, that starts new call frame, in which InSize bytes are set up inside ...
LLVM_ABI SDValue getTargetExtractSubreg(int SRIdx, const SDLoc &DL, EVT VT, SDValue Operand)
A convenience function for creating TargetInstrInfo::EXTRACT_SUBREG nodes.
SDValue getSelectCC(const SDLoc &DL, SDValue LHS, SDValue RHS, SDValue True, SDValue False, ISD::CondCode Cond, SDNodeFlags Flags=SDNodeFlags())
Helper function to make it easier to build SelectCC's if you just have an ISD::CondCode instead of an...
LLVM_ABI SDValue getSExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either sign-extending or trunca...
LLVM_ABI SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const MMOMetadata &Metadata=MMOMetadata())
Loads are not normal binary operators: their result type is not determined by their operands,...
LLVM_ABI bool isKnownNeverZero(SDValue Op, unsigned Depth=0) const
Test whether the given SDValue is known to contain non-zero value(s).
LLVM_ABI SDValue getExternalSymbol(const char *Sym, EVT VT)
const TargetMachine & getTarget() const
const LibcallLoweringInfo & getLibcalls() const
LLVM_ABI SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
LLVM_ABI SDValue getValueType(EVT)
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
LLVM_ABI OverflowKind computeOverflowForSignedAdd(SDValue N0, SDValue N1) const
Determine if the result of the signed addition of 2 nodes can overflow.
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
LLVM_ABI unsigned ComputeNumSignBits(SDValue Op, unsigned Depth=0) const
Return the number of times the sign bit of the register is replicated into the other bits.
LLVM_ABI SDValue getVectorIdxConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
LLVM_ABI void ReplaceAllUsesOfValueWith(SDValue From, SDValue To)
Replace any uses of From with To, leaving uses of other values produced by From.getNode() alone.
MachineFunction & getMachineFunction() const
SDValue getPOISON(EVT VT)
Return a POISON node. POISON does not have a useful SDLoc.
LLVM_ABI SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
LLVM_ABI KnownBits computeKnownBits(SDValue Op, unsigned Depth=0) const
Determine which bits of Op are known to be either zero or one and return them in Known.
LLVM_ABI SDValue getRegisterMask(const uint32_t *RegMask)
LLVM_ABI SDValue getZExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either zero-extending or trunca...
LLVM_ABI SDValue getCondCode(ISD::CondCode Cond)
void addCallSiteInfo(const SDNode *Node, CallSiteInfo &&CallInfo)
Set CallSiteInfo to be associated with Node.
LLVM_ABI bool MaskedValueIsZero(SDValue Op, const APInt &Mask, unsigned Depth=0) const
Return true if 'Op & Mask' is known to be zero.
SDValue getObjectPtrOffset(const SDLoc &SL, SDValue Ptr, TypeSize Offset)
Create an add instruction with appropriate flags when used for addressing some offset of an object.
LLVMContext * getContext() const
LLVM_ABI SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned TargetFlags=0)
LLVM_ABI SDValue CreateStackTemporary(TypeSize Bytes, Align Alignment)
Create a stack temporary based on the size in bytes and the alignment.
SDValue getTargetConstantPool(const Constant *C, EVT VT, MaybeAlign Align=std::nullopt, int Offset=0, unsigned TargetFlags=0)
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
LLVM_ABI SDValue getMaskedLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Base, SDValue Offset, SDValue Mask, SDValue Src0, EVT MemVT, MachineMemOperand *MMO, ISD::MemIndexedMode AM, ISD::LoadExtType, bool IsExpanding=false)
DenormalMode getDenormalMode(EVT VT) const
Return the current function's default denormal handling kind for the given floating point type.
LLVM_ABI std::pair< SDValue, SDValue > SplitScalar(const SDValue &N, const SDLoc &DL, const EVT &LoVT, const EVT &HiVT)
Split the scalar node with EXTRACT_ELEMENT using the provided VTs and return the low/high part.
LLVM_ABI SDValue getVectorShuffle(EVT VT, const SDLoc &dl, SDValue N1, SDValue N2, ArrayRef< int > Mask)
Return an ISD::VECTOR_SHUFFLE node.
LLVM_ABI SDValue getLogicalNOT(const SDLoc &DL, SDValue Val, EVT VT)
Create a logical NOT operation as (XOR Val, BooleanOne).
This instruction constructs a fixed permutation of two input vectors.
VectorType * getType() const
Overload to return most specific vector type.
static LLVM_ABI void getShuffleMask(const Constant *Mask, SmallVectorImpl< int > &Result)
Convert the input shuffle mask operand to a vector of integers.
static LLVM_ABI bool isIdentityMask(ArrayRef< int > Mask, int NumSrcElts)
Return true if this shuffle mask chooses elements from exactly one source vector without lane crossin...
This SDNode is used to implement the code generator support for the llvm IR shufflevector instruction...
int getMaskElt(unsigned Idx) const
ArrayRef< int > getMask() const
static LLVM_ABI bool isSplatMask(ArrayRef< int > Mask)
void insert_range(Range &&R)
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
bool empty() const
Definition SmallSet.h:169
bool erase(const T &V)
Definition SmallSet.h:200
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
Definition SmallSet.h:184
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
iterator insert(iterator I, T &&Elt)
void resize(size_type N)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
This class is used to represent ISD::STORE nodes.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
const unsigned char * bytes_end() const
Definition StringRef.h:125
constexpr size_t size() const
Get the string size.
Definition StringRef.h:144
constexpr const char * data() const
Get a pointer to the start of the string (which may not be null terminated).
Definition StringRef.h:138
const unsigned char * bytes_begin() const
Definition StringRef.h:122
static LLVM_ABI StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
Definition Type.cpp:467
TargetInstrInfo - Interface to description of machine instruction set.
Provides information about what library functions are available for the current target.
bool isOperationExpand(unsigned Op, EVT VT) const
Return true if the specified operation is illegal on this target or unlikely to be made legal with cu...
void setBooleanVectorContents(BooleanContent Ty)
Specify how the target extends the result of a vector boolean value from a vector of i1 to a wider ty...
void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
Indicate that the specified operation does not work with the specified type and indicate what to do a...
virtual void finalizeLowering(MachineFunction &MF) const
Execute target specific actions to finalize target lowering.
void setMaxDivRemBitWidthSupported(unsigned SizeInBits)
Set the size in bits of the maximum div/rem the backend supports.
bool PredictableSelectIsExpensive
Tells the code generator that select is more expensive than a branch if the branch is usually predict...
EVT getValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const
Return the EVT corresponding to this LLVM type.
unsigned MaxStoresPerMemcpyOptSize
Likewise for functions with the OptSize attribute.
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
ShiftLegalizationStrategy
Return the preferred strategy to legalize tihs SHIFT instruction, with ExpansionFactor being the recu...
void setMinStackArgumentAlignment(Align Alignment)
Set the minimum stack alignment of an argument.
const TargetMachine & getTargetMachine() const
virtual void insertSSPDeclarations(Module &M, const LibcallLoweringInfo &Libcalls) const
Inserts necessary declarations for SSP (stack protection) purpose.
void setIndexedMaskedLoadAction(unsigned IdxMode, MVT VT, LegalizeAction Action)
Indicate that the specified indexed masked load does or does not work with the specified type and ind...
void setIndexedLoadAction(ArrayRef< unsigned > IdxModes, MVT VT, LegalizeAction Action)
Indicate that the specified indexed load does or does not work with the specified type and indicate w...
void setPrefLoopAlignment(Align Alignment)
Set the target's preferred loop alignment.
void setMaxAtomicSizeInBitsSupported(unsigned SizeInBits)
Set the maximum atomic operation size supported by the backend.
Sched::Preference getSchedulingPreference() const
Return target scheduling preference.
void setMinFunctionAlignment(Align Alignment)
Set the target's minimum function alignment.
unsigned MaxStoresPerMemsetOptSize
Likewise for functions with the OptSize attribute.
void setBooleanContents(BooleanContent Ty)
Specify how the target extends the result of integer and floating point boolean values from i1 to a w...
unsigned MaxStoresPerMemmove
Specify maximum number of store instructions per memmove call.
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose.
unsigned MaxStoresPerMemmoveOptSize
Likewise for functions with the OptSize attribute.
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type.
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
void setIndexedStoreAction(ArrayRef< unsigned > IdxModes, MVT VT, LegalizeAction Action)
Indicate that the specified indexed store does or does not work with the specified type and indicate ...
ExtractSubvectorCost
Enum that specifies how expensive lowering an EXTRACT_SUBVECTOR is.
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
void setPrefFunctionAlignment(Align Alignment)
Set the target's preferred function alignment.
virtual unsigned getMaxSupportedInterleaveFactor() const
Get the maximum supported factor for interleaved memory accesses.
void setIndexedMaskedStoreAction(unsigned IdxMode, MVT VT, LegalizeAction Action)
Indicate that the specified indexed masked store does or does not work with the specified type and in...
unsigned MaxStoresPerMemset
Specify maximum number of store instructions per memset call.
void setTruncStoreAction(MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified truncating store does not work with the specified type and indicate what ...
virtual ShiftLegalizationStrategy preferredShiftLegalizationStrategy(SelectionDAG &DAG, SDNode *N, unsigned ExpansionFactor) const
bool isOperationLegalOrCustom(unsigned Op, EVT VT, bool LegalOnly=false) const
Return true if the specified operation is legal on this target or can be made legal with custom lower...
virtual bool allowsMemoryAccess(LLVMContext &Context, const DataLayout &DL, EVT VT, unsigned AddrSpace=0, Align Alignment=Align(1), MachineMemOperand::Flags Flags=MachineMemOperand::MONone, unsigned *Fast=nullptr) const
Return true if the target supports a memory access of this type for the given address space and align...
void setStackPointerRegisterToSaveRestore(Register R)
If set to a physical register, this specifies the register that llvm.savestack/llvm....
void AddPromotedToType(unsigned Opc, MVT OrigVT, MVT DestVT)
If Opc/OrigVT is specified as being promoted, the promotion code defaults to trying a larger integer/...
AtomicExpansionKind
Enum that specifies what an atomic load/AtomicRMWInst is expanded to, if at all.
virtual std::pair< const TargetRegisterClass *, uint8_t > findRepresentativeClass(const TargetRegisterInfo *TRI, MVT VT) const
Return the largest legal super-reg register class of the register class for the specified type and it...
RTLIB::LibcallImpl getLibcallImpl(RTLIB::Libcall Call) const
Get the libcall impl routine name for the specified libcall.
static StringRef getLibcallImplName(RTLIB::LibcallImpl Call)
Get the libcall routine name for the specified libcall implementation.
void setTargetDAGCombine(ArrayRef< ISD::NodeType > NTs)
Targets should invoke this method for each target independent node that they want to provide a custom...
void setLoadExtAction(unsigned ExtType, MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified load with extension does not work with the specified type and indicate wh...
LegalizeTypeAction getTypeAction(LLVMContext &Context, EVT VT) const
Return how we should legalize values of this type, either it is already legal (return 'Legal') or we ...
std::vector< ArgListEntry > ArgListTy
unsigned MaxStoresPerMemcpy
Specify maximum number of store instructions per memcpy call.
void setSchedulingPreference(Sched::Preference Pref)
Specify the target scheduling preference.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
bool SimplifyDemandedVectorElts(SDValue Op, const APInt &DemandedEltMask, APInt &KnownUndef, APInt &KnownZero, TargetLoweringOpt &TLO, unsigned Depth=0, bool AssumeSingleUse=false) const
Look at Vector Op.
void softenSetCCOperands(SelectionDAG &DAG, EVT VT, SDValue &NewLHS, SDValue &NewRHS, ISD::CondCode &CCCode, const SDLoc &DL, const SDValue OldLHS, const SDValue OldRHS) const
Soften the operands of a comparison.
SDValue expandUnalignedStore(StoreSDNode *ST, SelectionDAG &DAG) const
Expands an unaligned store to 2 half-size stores for integer values, and possibly more for vectors.
virtual ConstraintType getConstraintType(StringRef Constraint) const
Given a constraint, return the type of constraint it is for this target.
bool parametersInCSRMatch(const MachineRegisterInfo &MRI, const uint32_t *CallerPreservedMask, const SmallVectorImpl< CCValAssign > &ArgLocs, const SmallVectorImpl< SDValue > &OutVals) const
Check whether parameters to a call that are passed in callee saved registers are the same as from the...
std::pair< SDValue, SDValue > expandUnalignedLoad(LoadSDNode *LD, SelectionDAG &DAG) const
Expands an unaligned load to 2 half-size loads for an integer, and possibly more for vectors.
virtual SDValue LowerToTLSEmulatedModel(const GlobalAddressSDNode *GA, SelectionDAG &DAG) const
Lower TLS global address SDNode for target independent emulated TLS model.
std::pair< SDValue, SDValue > LowerCallTo(CallLoweringInfo &CLI) const
This function lowers an abstract call to a function into an actual call.
bool expandDIVREMByConstant(SDNode *N, SmallVectorImpl< SDValue > &Result, EVT HiLoVT, SelectionDAG &DAG, SDValue LL=SDValue(), SDValue LH=SDValue()) const
Attempt to expand an n-bit div/rem/divrem by constant using an n/2-bit algorithm.
bool isPositionIndependent() const
virtual ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const
Examine constraint string and operand type and determine a weight value.
SDValue buildLegalVectorShuffle(EVT VT, const SDLoc &DL, SDValue N0, SDValue N1, MutableArrayRef< int > Mask, SelectionDAG &DAG) const
Tries to build a legal vector shuffle using the provided parameters or equivalent variations.
virtual std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const
Given a physical register constraint (e.g.
bool SimplifyDemandedBits(SDValue Op, const APInt &DemandedBits, const APInt &DemandedElts, KnownBits &Known, TargetLoweringOpt &TLO, unsigned Depth=0, bool AssumeSingleUse=false) const
Look at Op.
virtual bool SimplifyDemandedBitsForTargetNode(SDValue Op, const APInt &DemandedBits, const APInt &DemandedElts, KnownBits &Known, TargetLoweringOpt &TLO, unsigned Depth=0) const
Attempt to simplify any target nodes based on the demanded bits/elts, returning true on success.
TargetLowering(const TargetLowering &)=delete
bool isConstTrueVal(SDValue N) const
Return if the N is a constant or constant vector equal to the true value from getBooleanContents().
virtual ArrayRef< MCPhysReg > getRoundingControlRegisters() const
Returns a 0 terminated array of rounding control registers that can be attached into strict FP call.
virtual bool canCreateUndefOrPoisonForTargetNode(SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG, UndefPoisonKind Kind, bool ConsiderFlags, unsigned Depth) const
Return true if Op can create undef or poison from non-undef & non-poison operands.
virtual void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const
Lower the specified operand into the Ops vector.
std::pair< SDValue, SDValue > makeLibCall(SelectionDAG &DAG, RTLIB::LibcallImpl LibcallImpl, EVT RetVT, ArrayRef< SDValue > Ops, MakeLibCallOptions CallOptions, const SDLoc &dl, SDValue Chain=SDValue()) const
Returns a pair of (return value, chain).
void setTypeIdForCallsiteInfo(const CallBase *CB, MachineFunction &MF, MachineFunction::CallSiteInfo &CSInfo) const
Primary interface to the complete machine description for the target machine.
TLSModel::Model getTLSModel(const GlobalValue *GV) const
Returns the TLS model which should be used for the given global variable.
const Triple & getTargetTriple() const
bool useEmulatedTLS() const
Returns true if this target uses emulated TLS.
virtual const TargetSubtargetInfo * getSubtargetImpl(const Function &) const
Virtual method implemented by subclasses that returns a reference to that target's TargetSubtargetInf...
TargetOptions Options
unsigned EnableFastISel
EnableFastISel - This flag enables fast-path instruction selection which trades away generated code q...
unsigned GuaranteedTailCallOpt
GuaranteedTailCallOpt - This flag is enabled when -tailcallopt is specified on the commandline.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
Target - Wrapper for Target specific information.
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:48
ObjectFormatType getObjectFormat() const
Get the object format for this triple.
Definition Triple.h:538
bool isOSWindows() const
Tests whether the OS is Windows.
Definition Triple.h:777
static constexpr TypeSize getFixed(ScalarTy ExactSize)
Definition TypeSize.h:339
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)
Definition Type.cpp:300
bool isVectorTy() const
True if this is an instance of VectorType.
Definition Type.h:283
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
Definition Type.cpp:299
bool isPointerTy() const
True if this is an instance of PointerType.
Definition Type.h:277
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
Definition Type.h:155
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
Definition Type.cpp:272
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
Definition Type.cpp:297
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
Definition Type.h:363
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
Definition Type.cpp:187
static LLVM_ABI IntegerType * getInt16Ty(LLVMContext &C)
Definition Type.cpp:298
bool isHalfTy() const
Return true if this is 'half', a 16-bit IEEE fp type.
Definition Type.h:144
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
Definition Type.h:130
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
Definition Type.cpp:222
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
Definition Type.h:186
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:252
bool isFPOrFPVectorTy() const
Return true if this is a FP type or a vector of FP.
Definition Type.h:222
A Use represents the edge between a Value definition and its users.
Definition Use.h:35
LLVM_ABI unsigned getOperandNo() const
Return the operand # of this use in its User.
Definition Use.cpp:35
User * getUser() const
Returns the User that contains this Use.
Definition Use.h:61
Value * getOperand(unsigned i) const
Definition User.h:207
unsigned getNumOperands() const
Definition User.h:229
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:257
bool hasOneUse() const
Return true if there is exactly one use of this value.
Definition Value.h:441
Base class of all SIMD vector types.
Type * getElementType() const
std::pair< iterator, bool > insert(const ValueT &V)
Definition DenseSet.h:209
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
Definition DenseSet.h:182
constexpr ScalarTy getFixedValue() const
Definition TypeSize.h:200
const ParentTy * getParent() const
Definition ilist_node.h:34
self_iterator getIterator()
Definition ilist_node.h:123
IteratorT end() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
static CondCodes getOppositeCondition(CondCodes CC)
Definition ARMBaseInfo.h:49
static ARMCC::CondCodes getSwappedCondition(ARMCC::CondCodes CC)
getSwappedCondition - assume the flags are set by MI(a,b), return the condition code if we modify the...
Definition ARMBaseInfo.h:72
@ SECREL
Thread Pointer Offset.
@ GOT_PREL
Thread Local Storage (General Dynamic Mode)
@ SBREL
Section Relative (Windows TLS)
@ GOTTPOFF
Global Offset Table, PC Relative.
@ TPOFF
Global Offset Table, Thread Pointer Offset.
TOF
Target Operand Flag enum.
@ MO_NONLAZY
MO_NONLAZY - This is an independent flag, on a symbol operand "FOO" it represents a symbol which,...
@ MO_SBREL
MO_SBREL - On a symbol operand, this represents a static base relative relocation.
@ MO_DLLIMPORT
MO_DLLIMPORT - On a symbol operand, this represents that the reference to the symbol is for an import...
@ MO_GOT
MO_GOT - On a symbol operand, this represents a GOT relative relocation.
@ MO_COFFSTUB
MO_COFFSTUB - On a symbol operand "FOO", this indicates that the reference is actually to the "....
static ShiftOpc getShiftOpcForNode(unsigned Opcode)
int getSOImmVal(unsigned Arg)
getSOImmVal - Given a 32-bit immediate, if it is something that can fit into an shifter_operand immed...
int getFP32Imm(const APInt &Imm)
getFP32Imm - Return an 8-bit floating-point version of the 32-bit floating-point value.
uint64_t decodeVMOVModImm(unsigned ModImm, unsigned &EltBits)
decodeVMOVModImm - Decode a NEON/MVE modified immediate value into the element value and the element ...
unsigned getAM2Offset(unsigned AM2Opc)
bool isThumbImmShiftedVal(unsigned V)
isThumbImmShiftedVal - Return true if the specified value can be obtained by left shifting a 8-bit im...
int getT2SOImmVal(unsigned Arg)
getT2SOImmVal - Given a 32-bit immediate, if it is something that can fit into a Thumb-2 shifter_oper...
unsigned createVMOVModImm(unsigned OpCmode, unsigned Val)
int getFP64Imm(const APInt &Imm)
getFP64Imm - Return an 8-bit floating-point version of the 64-bit floating-point value.
int getFP16Imm(const APInt &Imm)
getFP16Imm - Return an 8-bit floating-point version of the 16-bit floating-point value.
unsigned getSORegOpc(ShiftOpc ShOp, unsigned Imm)
int getFP32FP16Imm(const APInt &Imm)
If this is a FP16Imm encoded as a fp32 value, return the 8-bit encoding for it.
AddrOpc getAM2Op(unsigned AM2Opc)
bool isBitFieldInvertedMask(unsigned v)
const unsigned FPStatusBits
FastISel * createFastISel(FunctionLoweringInfo &funcInfo, const TargetLibraryInfo *libInfo, const LibcallLoweringInfo *libcallLowering)
const unsigned FPReservedBits
const unsigned RoundingBitsPos
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ Entry
Definition COFF.h:862
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
@ Swift
Calling convention for Swift.
Definition CallingConv.h:69
@ ARM_APCS
ARM Procedure Calling Standard (obsolete, but still used on some targets).
@ CFGuard_Check
Special calling convention on Windows for calling the Control Guard Check ICall funtion.
Definition CallingConv.h:82
@ PreserveMost
Used for runtime calls that preserves most registers.
Definition CallingConv.h:63
@ ARM_AAPCS
ARM Architecture Procedure Calling Standard calling convention (aka EABI).
@ CXX_FAST_TLS
Used for access functions.
Definition CallingConv.h:72
@ GHC
Used by the Glasgow Haskell Compiler (GHC).
Definition CallingConv.h:50
@ PreserveAll
Used for runtime calls that preserves (almost) all registers.
Definition CallingConv.h:66
@ Fast
Attempts to make calls as fast as possible (e.g.
Definition CallingConv.h:41
@ Tail
Attemps to make calls as fast as possible while guaranteeing that tail call optimization can always b...
Definition CallingConv.h:76
@ SwiftTail
This follows the Swift calling convention in how arguments are passed but guarantees tail calls will ...
Definition CallingConv.h:87
@ ARM_AAPCS_VFP
Same as ARM_AAPCS, but uses hard floating point ABI.
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
bool isNON_EXTLoad(const SDNode *N)
Returns true if the specified node is a non-extending load.
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
Definition ISDOpcodes.h:41
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
Definition ISDOpcodes.h:830
@ MERGE_VALUES
MERGE_VALUES - This node takes multiple discrete operands and returns them all as its individual resu...
Definition ISDOpcodes.h:261
@ STACKRESTORE
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain.
@ STACKSAVE
STACKSAVE - STACKSAVE has one operand, an input chain.
@ STRICT_FSETCC
STRICT_FSETCC/STRICT_FSETCCS - Constrained versions of SETCC, used for floating-point operands only.
Definition ISDOpcodes.h:514
@ POISON
POISON - A poison node.
Definition ISDOpcodes.h:236
@ SET_FPENV
Sets the current floating-point environment.
@ MLOAD
Masked load and store - consecutive vector load and store operations with additional mask operand tha...
@ EH_SJLJ_LONGJMP
OUTCHAIN = EH_SJLJ_LONGJMP(INCHAIN, buffer) This corresponds to the eh.sjlj.longjmp intrinsic.
Definition ISDOpcodes.h:168
@ FGETSIGN
INT = FGETSIGN(FP) - Return the sign bit of the specified floating point value as an integer 0/1 valu...
Definition ISDOpcodes.h:541
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
Definition ISDOpcodes.h:275
@ INSERT_SUBVECTOR
INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector with VECTOR2 inserted into VECTOR1.
Definition ISDOpcodes.h:603
@ BSWAP
Byte Swap and Counting operators.
Definition ISDOpcodes.h:790
@ VAEND
VAEND, VASTART - VAEND and VASTART have three operands: an input chain, pointer, and a SRCVALUE.
@ ATOMIC_STORE
OUTCHAIN = ATOMIC_STORE(INCHAIN, val, ptr) This corresponds to "store atomic" instruction.
@ RESET_FPENV
Set floating-point environment to default state.
@ ADD
Simple integer binary arithmetic operators.
Definition ISDOpcodes.h:264
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ SET_FPMODE
Sets the current dynamic floating-point control modes.
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
Definition ISDOpcodes.h:864
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
Definition ISDOpcodes.h:521
@ FMODF
FMODF - Decomposes the operand into integral and fractional parts, each having the same type and sign...
@ FATAN2
FATAN2 - atan2, inspired by libm.
@ FSINCOSPI
FSINCOSPI - Compute both the sine and cosine times pi more accurately than FSINCOS(pi*x),...
@ INTRINSIC_VOID
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
Definition ISDOpcodes.h:220
@ EH_SJLJ_SETUP_DISPATCH
OUTCHAIN = EH_SJLJ_SETUP_DISPATCH(INCHAIN) The target initializes the dispatch table here.
Definition ISDOpcodes.h:172
@ GlobalAddress
Definition ISDOpcodes.h:88
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
Definition ISDOpcodes.h:891
@ CONCAT_VECTORS
CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of vector type with the same length ...
Definition ISDOpcodes.h:587
@ VECREDUCE_FMAX
FMIN/FMAX nodes can have flags, for NaN/NoNaN variants.
@ FADD
Simple binary floating point operators.
Definition ISDOpcodes.h:418
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
Definition ISDOpcodes.h:750
@ ATOMIC_FENCE
OUTCHAIN = ATOMIC_FENCE(INCHAIN, ordering, scope) This corresponds to the fence instruction.
@ RESET_FPMODE
Sets default dynamic floating-point control modes.
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
Definition ISDOpcodes.h:280
@ FP16_TO_FP
FP16_TO_FP, FP_TO_FP16 - These operators are used to perform promotions and truncation for half-preci...
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ BUILD_PAIR
BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.
Definition ISDOpcodes.h:254
@ FLDEXP
FLDEXP - ldexp, inspired by libm (op0 * 2**op1).
@ STRICT_FSQRT
Constrained versions of libm-equivalent floating point intrinsics.
Definition ISDOpcodes.h:439
@ BUILTIN_OP_END
BUILTIN_OP_END - This must be the last enum value in this list.
@ GlobalTLSAddress
Definition ISDOpcodes.h:89
@ CTLZ_ZERO_POISON
Definition ISDOpcodes.h:799
@ SET_ROUNDING
Set rounding mode.
Definition ISDOpcodes.h:986
@ SIGN_EXTEND
Conversion operators.
Definition ISDOpcodes.h:855
@ AVGCEILS
AVGCEILS/AVGCEILU - Rounding averaging add - Add two integers using an integer of type i[N+2],...
Definition ISDOpcodes.h:718
@ STRICT_UINT_TO_FP
Definition ISDOpcodes.h:488
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
Definition ISDOpcodes.h:668
@ BR
Control flow instructions. These all have token chains.
@ VECREDUCE_FADD
These reductions have relaxed evaluation order semantics, and have a single vector operand.
@ PREFETCH
PREFETCH - This corresponds to a prefetch intrinsic.
@ FSINCOS
FSINCOS - Compute both fsin and fcos as a single operation.
@ SETCCCARRY
Like SetCC, ops #0 and #1 are the LHS and RHS operands to compare, but op #2 is a boolean indicating ...
Definition ISDOpcodes.h:838
@ FNEG
Perform various unary floating-point operations inspired by libm.
@ BR_CC
BR_CC - Conditional branch.
@ SSUBO
Same for subtraction.
Definition ISDOpcodes.h:353
@ BR_JT
BR_JT - Jumptable branch.
@ SSUBSAT
RESULT = [US]SUBSAT(LHS, RHS) - Perform saturation subtraction on 2 integers with the same bit width ...
Definition ISDOpcodes.h:375
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
Definition ISDOpcodes.h:807
@ ATOMIC_LOAD
Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) This corresponds to "load atomic" instruction.
@ UNDEF
UNDEF - An undefined node.
Definition ISDOpcodes.h:233
@ EXTRACT_ELEMENT
EXTRACT_ELEMENT - This is used to get the lower or upper (determined by a Constant,...
Definition ISDOpcodes.h:247
@ VACOPY
VACOPY - VACOPY has 5 operands: an input chain, a destination pointer, a source pointer,...
@ BasicBlock
Various leaf nodes.
Definition ISDOpcodes.h:81
@ CopyFromReg
CopyFromReg - This node indicates that the input value is a virtual or physical register that is defi...
Definition ISDOpcodes.h:230
@ SADDO
RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
Definition ISDOpcodes.h:349
@ CTLS
Count leading redundant sign bits.
Definition ISDOpcodes.h:803
@ VECREDUCE_ADD
Integer reductions may have a result type larger than the vector element type.
@ GET_ROUNDING
Returns current rounding mode: -1 Undefined 0 Round to 0 1 Round to nearest, ties to even 2 Round to ...
Definition ISDOpcodes.h:981
@ STRICT_FP_TO_FP16
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
Definition ISDOpcodes.h:707
@ GET_FPMODE
Reads the current dynamic floating-point control modes.
@ STRICT_FP16_TO_FP
@ GET_FPENV
Gets the current floating-point environment.
@ SHL
Shift and rotation operations.
Definition ISDOpcodes.h:772
@ VECTOR_SHUFFLE
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
Definition ISDOpcodes.h:652
@ EXTRACT_SUBVECTOR
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR.
Definition ISDOpcodes.h:617
@ READ_REGISTER
READ_REGISTER, WRITE_REGISTER - This node represents llvm.register on the DAG, which implements the n...
Definition ISDOpcodes.h:139
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
Definition ISDOpcodes.h:579
@ CopyToReg
CopyToReg - This node has three operands: a chain, a register number to set to this value,...
Definition ISDOpcodes.h:224
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
Definition ISDOpcodes.h:861
@ DEBUGTRAP
DEBUGTRAP - Trap intended to get the attention of a debugger.
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
Definition ISDOpcodes.h:822
@ ATOMIC_CMP_SWAP
Val, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap) For double-word atomic operations: ValLo,...
@ FMINNUM
FMINNUM/FMAXNUM - Perform floating-point minimum maximum on two values, following IEEE-754 definition...
@ SMULO
Same for multiplication.
Definition ISDOpcodes.h:357
@ DYNAMIC_STACKALLOC
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary.
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
Definition ISDOpcodes.h:899
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
Definition ISDOpcodes.h:730
@ FP_EXTEND
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
Definition ISDOpcodes.h:989
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
Definition ISDOpcodes.h:816
@ UADDO_CARRY
Carry-using nodes for multiple precision addition and subtraction.
Definition ISDOpcodes.h:329
@ STRICT_SINT_TO_FP
STRICT_[US]INT_TO_FP - Convert a signed or unsigned integer to a floating point value.
Definition ISDOpcodes.h:487
@ STRICT_FROUNDEVEN
Definition ISDOpcodes.h:467
@ BF16_TO_FP
BF16_TO_FP, FP_TO_BF16 - These operators are used to perform promotions and truncation for bfloat16.
@ FRAMEADDR
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG.
Definition ISDOpcodes.h:110
@ STRICT_FP_TO_UINT
Definition ISDOpcodes.h:481
@ STRICT_FP_ROUND
X = STRICT_FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision ...
Definition ISDOpcodes.h:503
@ STRICT_FP_TO_SINT
STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
Definition ISDOpcodes.h:480
@ FMINIMUM
FMINIMUM/FMAXIMUM - NaN-propagating minimum/maximum that also treat -0.0 as less than 0....
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
Definition ISDOpcodes.h:937
@ READCYCLECOUNTER
READCYCLECOUNTER - This corresponds to the readcyclecounter intrinsic.
@ STRICT_FP_EXTEND
X = STRICT_FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
Definition ISDOpcodes.h:508
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition ISDOpcodes.h:742
@ TRAP
TRAP - Trapping instruction.
@ INTRINSIC_WO_CHAIN
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
Definition ISDOpcodes.h:205
@ SCMP
[US]CMP - 3-way comparison of signed or unsigned integers.
Definition ISDOpcodes.h:738
@ AVGFLOORS
AVGFLOORS/AVGFLOORU - Averaging add - Add two integers using an integer of type i[N+1],...
Definition ISDOpcodes.h:713
@ STRICT_FADD
Constrained versions of the binary floating point operators.
Definition ISDOpcodes.h:428
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
Definition ISDOpcodes.h:568
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
Definition ISDOpcodes.h:53
@ ATOMIC_SWAP
Val, OUTCHAIN = ATOMIC_SWAP(INCHAIN, ptr, amt) Val, OUTCHAIN = ATOMIC_LOAD_[OpName](INCHAIN,...
@ CTTZ_ZERO_POISON
Bit counting operators with a poisoned result for zero inputs.
Definition ISDOpcodes.h:798
@ FFREXP
FFREXP - frexp, extract fractional and exponent component of a floating-point value.
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
Definition ISDOpcodes.h:970
@ SPONENTRY
SPONENTRY - Represents the llvm.sponentry intrinsic.
Definition ISDOpcodes.h:122
@ STRICT_FNEARBYINT
Definition ISDOpcodes.h:459
@ FP_TO_SINT_SAT
FP_TO_[US]INT_SAT - Convert floating point value in operand 0 to a signed or unsigned scalar integer ...
Definition ISDOpcodes.h:956
@ EH_SJLJ_SETJMP
RESULT, OUTCHAIN = EH_SJLJ_SETJMP(INCHAIN, buffer) This corresponds to the eh.sjlj....
Definition ISDOpcodes.h:162
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
Definition ISDOpcodes.h:867
@ VAARG
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
@ BRCOND
BRCOND - Conditional branch.
@ SHL_PARTS
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations.
Definition ISDOpcodes.h:844
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
Definition ISDOpcodes.h:537
@ SADDSAT
RESULT = [US]ADDSAT(LHS, RHS) - Perform saturation addition on 2 integers with the same bit width (W)...
Definition ISDOpcodes.h:366
@ ABDS
ABDS/ABDU - Absolute difference - Return the absolute difference between two numbers interpreted as s...
Definition ISDOpcodes.h:725
@ SADDO_CARRY
Carry-using overflow-aware nodes for multiple precision addition and subtraction.
Definition ISDOpcodes.h:339
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
Definition ISDOpcodes.h:213
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
Definition ISDOpcodes.h:559
bool isNormalStore(const SDNode *N)
Returns true if the specified node is a non-truncating and unindexed store.
bool isZEXTLoad(const SDNode *N)
Returns true if the specified node is a ZEXTLOAD.
LLVM_ABI CondCode getSetCCInverse(CondCode Operation, EVT Type)
Return the operation corresponding to !(X op Y), where 'op' is a valid SetCC operation.
bool isEXTLoad(const SDNode *N)
Returns true if the specified node is a EXTLOAD.
LLVM_ABI CondCode getSetCCSwappedOperands(CondCode Operation)
Return the operation corresponding to (Y op X) when given the operation for (X op Y).
LLVM_ABI bool isBuildVectorAllZeros(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR where all of the elements are 0 or undef.
bool isSignedIntSetCC(CondCode Code)
Return true if this is a setcc instruction that performs a signed comparison when used with integer o...
LLVM_ABI bool isConstantSplatVector(const SDNode *N, APInt &SplatValue)
Node predicates.
MemIndexedMode
MemIndexedMode enum - This enum defines the load / store indexed addressing modes.
bool isSEXTLoad(const SDNode *N)
Returns true if the specified node is a SEXTLOAD.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
static const int LAST_INDEXED_MODE
bool isNormalLoad(const SDNode *N)
Returns true if the specified node is a non-extending and unindexed load.
This namespace contains an enum with a value for every intrinsic/builtin function known by LLVM.
LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > OverloadTys={})
Look up the Function declaration of the intrinsic id in the Module M.
LLVM_ABI Libcall getSINTTOFP(EVT OpVT, EVT RetVT)
getSINTTOFP - Return the SINTTOFP_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getUINTTOFP(EVT OpVT, EVT RetVT)
getUINTTOFP - Return the UINTTOFP_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getFPTOUINT(EVT OpVT, EVT RetVT)
getFPTOUINT - Return the FPTOUINT_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getFPTOSINT(EVT OpVT, EVT RetVT)
getFPTOSINT - Return the FPTOSINT_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getFPEXT(EVT OpVT, EVT RetVT)
getFPEXT - Return the FPEXT_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getFPROUND(EVT OpVT, EVT RetVT)
getFPROUND - Return the FPROUND_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
@ SingleThread
Synchronized with respect to signal handlers executing in the same thread.
Definition LLVMContext.h:55
initializer< Ty > init(const Ty &Val)
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
Definition SFrame.h:77
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition STLExtras.h:316
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
bool RetFastCC_ARM_APCS(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
@ Low
Lower the current thread's priority such that it does not affect foreground tasks significantly.
Definition Threading.h:280
@ Offset
Definition DWP.cpp:577
@ Length
Definition DWP.cpp:577
void stable_sort(R &&Range)
Definition STLExtras.h:2132
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1781
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1755
bool HasLowerConstantMaterializationCost(unsigned Val1, unsigned Val2, const ARMSubtarget *Subtarget, bool ForCodesize=false)
Returns true if Val1 has a lower Constant Materialization Cost than Val2.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
InstructionCost Cost
LLVM_ABI bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
RelativeUniformCounterPtr Values
Definition InstrProf.h:91
@ Known
Known to have no common set bits.
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Dead
Unused definition.
@ Kill
The last use of a register.
@ Define
Register definition.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
bool isStrongerThanMonotonic(AtomicOrdering AO)
int countr_one(T Value)
Count the number of ones from the least significant bit to the first zero bit.
Definition bit.h:315
bool CCAssignFn(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
CCAssignFn - This function assigns a location for Val, updating State to reflect the change.
bool CC_ARM_AAPCS(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
constexpr bool isMask_32(uint32_t Value)
Return true if the argument is a non-empty sequence of ones starting at the least significant bit wit...
Definition MathExtras.h:256
@ Load
The value being inserted comes from a load (InsertElement only).
@ Store
The extracted value is stored (ExtractElement only).
bool RetCC_ARM_AAPCS_VFP(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
bool RetCC_ARM_APCS(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
int bit_width(T Value)
Returns the number of bits needed to represent Value if Value is nonzero.
Definition bit.h:325
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
Definition STLExtras.h:2224
constexpr bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
Definition MathExtras.h:244
bool RetCC_ARM_AAPCS(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
LLVM_ABI Value * concatenateVectors(IRBuilderBase &Builder, ArrayRef< Value * > Vecs)
Concatenate a list of vectors.
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
Definition MathExtras.h:285
void shuffle(Iterator first, Iterator last, RNG &&g)
Definition STLExtras.h:1546
bool CC_ARM_APCS_GHC(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
static std::array< MachineOperand, 2 > predOps(ARMCC::CondCodes Pred, unsigned PredReg=0)
Get the operands corresponding to the given Pred value.
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
constexpr bool isShiftedMask_32(uint32_t Value)
Return true if the argument contains a non-empty sequence of ones with the remainder zero (32 bit ver...
Definition MathExtras.h:268
LLVM_ABI ConstantFPSDNode * isConstOrConstSplatFP(SDValue N, bool AllowUndefs=false)
Returns the SDNode if it is a constant splat BuildVector or constant float.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
Definition bit.h:204
bool isReleaseOrStronger(AtomicOrdering AO)
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:753
constexpr bool has_single_bit(T Value) noexcept
Definition bit.h:149
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1762
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition MathExtras.h:326
int countl_zero(T Val)
Count number of 0's from the most significant bit to the least stopping at the first 1.
Definition bit.h:263
LLVM_ABI bool isBitwiseNot(SDValue V, bool AllowUndefs=false)
Returns true if V is a bitwise not operation.
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition MathExtras.h:280
bool FastCC_ARM_APCS(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
bool CC_ARM_Win32_CFGuard_Check(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition Alignment.h:144
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
Definition MathExtras.h:190
SmallVector< ValueTypeFromRangeType< R >, Size > to_vector(R &&Range)
Given a range of type R, iterate the entire range and return a SmallVector with elements of the vecto...
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
const unsigned PerfectShuffleTable[6561+1]
AtomicOrdering
Atomic ordering for LLVM's memory model.
@ Other
Any other memory.
Definition ModRef.h:68
CombineLevel
Definition DAGCombine.h:15
@ BeforeLegalizeTypes
Definition DAGCombine.h:16
unsigned ConstantMaterializationCost(unsigned Val, const ARMSubtarget *Subtarget, bool ForCodesize=false)
Returns the number of instructions required to materialize the given constant in a register,...
@ Mul
Product of integers.
@ And
Bitwise or logical AND of integers.
@ Sub
Subtraction of integers.
@ Add
Sum of integers.
@ FAdd
Sum of floats.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
Definition MCRegister.h:21
@ Fast
Assign the register banks as fast as possible (default).
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
Definition InstrProf.h:145
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
LLVM_ABI ConstantSDNode * isConstOrConstSplat(SDValue N, bool AllowUndefs=false, bool AllowTruncation=false)
Returns the SDNode if it is a constant splat BuildVector or constant int.
constexpr U AbsoluteValue(T X)
Return the absolute value of a signed integer, converted to the corresponding unsigned integer type.
Definition MathExtras.h:587
bool isAcquireOrStronger(AtomicOrdering AO)
constexpr unsigned BitWidth
ExceptionHandling
Definition CodeGen.h:54
@ SjLj
setjmp/longjmp based exceptions
Definition CodeGen.h:58
static MachineOperand t1CondCodeOp(bool isDead=false)
Get the operand corresponding to the conditional code result for Thumb1.
auto count_if(R &&Range, UnaryPredicate P)
Wrapper function around std::count_if to count the number of times an element satisfying a given pred...
Definition STLExtras.h:2035
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1788
constexpr auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
Definition Sequence.h:341
LLVM_ABI bool isOneConstant(SDValue V)
Returns true if V is a constant integer one.
UndefPoisonKind
Enumeration to track whether we are interested in Undef, Poison, or both.
Definition UndefPoison.h:20
constexpr bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
Definition MathExtras.h:249
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
Definition Alignment.h:201
static MachineOperand condCodeOp(unsigned CCReg=0)
Get the operand corresponding to the conditional code result.
bool isVREVMask(ArrayRef< int > M, EVT VT, unsigned BlockSize)
isVREVMask - Check if a vector shuffle corresponds to a VREV instruction with the specified blocksize...
unsigned gettBLXrOpcode(const MachineFunction &MF)
bool CC_ARM_APCS(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
@ Increment
Incrementally increasing token ID.
Definition AllocToken.h:26
bool CC_ARM_AAPCS_VFP(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
LLVM_ABI llvm::SmallVector< int, 16 > createSequentialMask(unsigned Start, unsigned NumInts, unsigned NumUndefs)
Create a sequential shuffle mask.
constexpr bool isShiftedUInt(uint64_t x)
Checks if a unsigned integer is an N bit number shifted left by S.
Definition MathExtras.h:199
unsigned convertAddSubFlagsOpcode(unsigned OldOpc)
Map pseudo instructions that imply an 'S' bit onto real opcodes.
LLVM_ABI bool isAllOnesConstant(SDValue V)
Returns true if V is an integer constant with all bits set.
MCRegisterClass TargetRegisterClass
Definition FastISel.h:58
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
Definition Error.cpp:177
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:880
#define N
Load/store instruction that can be merged with a base address update.
SDNode * N
Instruction that updates a pointer.
unsigned ConstInc
Pointer increment value if it is a constant, or 0 otherwise.
SDValue Inc
Pointer increment operand.
A collection of metadata nodes that might be associated with a memory access used by the alias-analys...
Definition Metadata.h:774
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
static constexpr DenormalMode getIEEE()
Extended Value Type.
Definition ValueTypes.h:35
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
Definition ValueTypes.h:90
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
Definition ValueTypes.h:145
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT.
Definition ValueTypes.h:70
bool bitsGT(EVT VT) const
Return true if this has more bits than VT.
Definition ValueTypes.h:307
bool bitsLT(EVT VT) const
Return true if this has less bits than VT.
Definition ValueTypes.h:323
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
Definition ValueTypes.h:155
ElementCount getVectorElementCount() const
Definition ValueTypes.h:373
EVT getDoubleNumVectorElementsVT(LLVMContext &Context) const
Definition ValueTypes.h:494
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
Definition ValueTypes.h:396
unsigned getVectorMinNumElements() const
Given a vector type, return the minimum number of elements it contains.
Definition ValueTypes.h:382
uint64_t getScalarSizeInBits() const
Definition ValueTypes.h:408
bool isPow2VectorType() const
Returns true if the given vector is a power of 2.
Definition ValueTypes.h:501
static LLVM_ABI EVT getEVT(Type *Ty, bool HandleUnknown=false)
Return the value type corresponding to the specified type.
EVT changeVectorElementType(LLVMContext &Context, EVT EltVT) const
Return a VT for a vector type whose attributes match ourselves with the exception of the element type...
Definition ValueTypes.h:98
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition ValueTypes.h:339
bool is128BitVector() const
Return true if this is a 128-bit vector type.
Definition ValueTypes.h:230
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
Definition ValueTypes.h:61
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
Definition ValueTypes.h:404
bool isFixedLengthVector() const
Definition ValueTypes.h:199
static EVT getFloatingPointVT(unsigned BitWidth)
Returns the EVT that represents a floating-point type with the given number of bits.
Definition ValueTypes.h:55
bool isVector() const
Return true if this is a vector value type.
Definition ValueTypes.h:176
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
Definition ValueTypes.h:346
LLVM_ABI Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
Definition ValueTypes.h:351
bool isScalarInteger() const
Return true if this is an integer, but not a vector.
Definition ValueTypes.h:165
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
Definition ValueTypes.h:359
bool bitsLE(EVT VT) const
Return true if this has no more bits than VT.
Definition ValueTypes.h:331
EVT getHalfNumVectorElementsVT(LLVMContext &Context) const
Definition ValueTypes.h:484
bool isInteger() const
Return true if this is an integer or a vector integer type.
Definition ValueTypes.h:160
bool is64BitVector() const
Return true if this is a 64-bit vector type.
Definition ValueTypes.h:225
InputArg - This struct carries flags and type information about a single incoming (formal) argument o...
EVT ArgVT
Usually the non-legalized type of the argument, which is the EVT corresponding to the OrigTy IR type.
static KnownBits makeConstant(const APInt &C)
Create known bits from a known constant.
Definition KnownBits.h:315
unsigned getBitWidth() const
Get the bit width of this value.
Definition KnownBits.h:44
KnownBits zext(unsigned BitWidth) const
Return known bits for a zero extension of the value we're tracking.
Definition KnownBits.h:176
static KnownBits add(const KnownBits &LHS, const KnownBits &RHS, bool NSW=false, bool NUW=false, bool SelfAdd=false)
Compute knownbits resulting from addition of LHS and RHS.
Definition KnownBits.h:361
KnownBits intersectWith(const KnownBits &RHS) const
Returns KnownBits information that is known to be true for both this and RHS.
Definition KnownBits.h:325
static LLVM_ABI KnownBits mul(const KnownBits &LHS, const KnownBits &RHS, bool NoUndefSelfMultiply=false)
Compute known bits resulting from multiplying LHS and RHS.
APInt getSignedMinValue() const
Return the minimal signed value possible given these KnownBits.
Definition KnownBits.h:136
Matching combinators.
SmallVector< ArgRegPair, 1 > ArgRegPairs
Vector of call argument and its forwarding register.
This class contains a discriminated union of information about pointers in memory operands,...
static LLVM_ABI MachinePointerInfo getJumpTable(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a jump table entry.
static LLVM_ABI MachinePointerInfo getStack(MachineFunction &MF, int64_t Offset, uint8_t ID=0)
Stack pointer relative access.
static LLVM_ABI MachinePointerInfo getConstantPool(MachineFunction &MF)
Return a MachinePointerInfo record that refers to the constant pool.
static LLVM_ABI MachinePointerInfo getGOT(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a GOT entry.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Definition Alignment.h:106
These are IR-level optimization flags that may be propagated to SDNodes.
bool hasNoSignedZeros() const
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
This represents an addressing mode of: BaseGV + BaseOffs + BaseReg + Scale*ScaleReg + ScalableOffset*...
This contains information for each constraint that we are lowering.
This structure contains all information that is necessary for lowering calls.
CallLoweringInfo & setInRegister(bool Value=true)
CallLoweringInfo & setLibCallee(CallingConv::ID CC, Type *ResultType, SDValue Target, ArgListTy &&ArgsList)
SmallVector< ISD::InputArg, 32 > Ins
CallLoweringInfo & setZExtResult(bool Value=true)
CallLoweringInfo & setDebugLoc(const SDLoc &dl)
CallLoweringInfo & setSExtResult(bool Value=true)
SmallVector< ISD::OutputArg, 32 > Outs
CallLoweringInfo & setChain(SDValue InChain)
CallLoweringInfo & setCallee(CallingConv::ID CC, Type *ResultType, SDValue Target, ArgListTy &&ArgsList, AttributeSet ResultAttrs={})
LLVM_ABI void AddToWorklist(SDNode *N)
LLVM_ABI SDValue CombineTo(SDNode *N, ArrayRef< SDValue > To, bool AddTo=true)
This structure is used to pass arguments to makeLibCall function.
A convenience struct that encapsulates a DAG, and two SDValues for returning information from TargetL...