LLVM 24.0.0git
SystemZISelLowering.cpp
Go to the documentation of this file.
1//===-- SystemZISelLowering.cpp - SystemZ 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 implements the SystemZTargetLowering class.
10//
11//===----------------------------------------------------------------------===//
12
13#include "SystemZISelLowering.h"
14#include "SystemZCallingConv.h"
17#include "llvm/ADT/SmallSet.h"
22#include "llvm/IR/GlobalAlias.h"
24#include "llvm/IR/Intrinsics.h"
25#include "llvm/IR/IntrinsicsS390.h"
26#include "llvm/IR/Module.h"
32#include <cctype>
33#include <optional>
34
35using namespace llvm;
36
37#define DEBUG_TYPE "systemz-lower"
38
39// Temporarily let this be disabled by default until all known problems
40// related to argument extensions are fixed.
42 "argext-abi-check", cl::init(false),
43 cl::desc("Verify that narrow int args are properly extended per the "
44 "SystemZ ABI."));
45
46namespace {
47// Represents information about a comparison.
48struct Comparison {
49 Comparison(SDValue Op0In, SDValue Op1In, SDValue ChainIn)
50 : Op0(Op0In), Op1(Op1In), Chain(ChainIn),
51 Opcode(0), ICmpType(0), CCValid(0), CCMask(0) {}
52
53 // The operands to the comparison.
54 SDValue Op0, Op1;
55
56 // Chain if this is a strict floating-point comparison.
57 SDValue Chain;
58
59 // The opcode that should be used to compare Op0 and Op1.
60 unsigned Opcode;
61
62 // A SystemZICMP value. Only used for integer comparisons.
63 unsigned ICmpType;
64
65 // The mask of CC values that Opcode can produce.
66 unsigned CCValid;
67
68 // The mask of CC values for which the original condition is true.
69 unsigned CCMask;
70};
71} // end anonymous namespace
72
73// Classify VT as either 32 or 64 bit.
74static bool is32Bit(EVT VT) {
75 switch (VT.getSimpleVT().SimpleTy) {
76 case MVT::i32:
77 return true;
78 case MVT::i64:
79 return false;
80 default:
81 llvm_unreachable("Unsupported type");
82 }
83}
84
85// Return a version of MachineOperand that can be safely used before the
86// final use.
88 if (Op.isReg())
89 Op.setIsKill(false);
90 return Op;
91}
92
94 const SystemZSubtarget &STI)
95 : TargetLowering(TM, STI), Subtarget(STI) {
96 MVT PtrVT = MVT::getIntegerVT(TM.getPointerSizeInBits(0));
97
98 auto *Regs = STI.getSpecialRegisters();
99
100 // Set up the register classes.
101 if (Subtarget.hasHighWord())
102 addRegisterClass(MVT::i32, &SystemZ::GRX32BitRegClass);
103 else
104 addRegisterClass(MVT::i32, &SystemZ::GR32BitRegClass);
105 addRegisterClass(MVT::i64, &SystemZ::GR64BitRegClass);
106 if (!useSoftFloat()) {
107 if (Subtarget.hasVector()) {
108 addRegisterClass(MVT::f16, &SystemZ::VR16BitRegClass);
109 addRegisterClass(MVT::f32, &SystemZ::VR32BitRegClass);
110 addRegisterClass(MVT::f64, &SystemZ::VR64BitRegClass);
111 } else {
112 addRegisterClass(MVT::f16, &SystemZ::FP16BitRegClass);
113 addRegisterClass(MVT::f32, &SystemZ::FP32BitRegClass);
114 addRegisterClass(MVT::f64, &SystemZ::FP64BitRegClass);
115 }
116 if (Subtarget.hasVectorEnhancements1())
117 addRegisterClass(MVT::f128, &SystemZ::VR128BitRegClass);
118 else
119 addRegisterClass(MVT::f128, &SystemZ::FP128BitRegClass);
120
121 if (Subtarget.hasVector()) {
122 addRegisterClass(MVT::v16i8, &SystemZ::VR128BitRegClass);
123 addRegisterClass(MVT::v8i16, &SystemZ::VR128BitRegClass);
124 addRegisterClass(MVT::v4i32, &SystemZ::VR128BitRegClass);
125 addRegisterClass(MVT::v2i64, &SystemZ::VR128BitRegClass);
126 addRegisterClass(MVT::v8f16, &SystemZ::VR128BitRegClass);
127 addRegisterClass(MVT::v4f32, &SystemZ::VR128BitRegClass);
128 addRegisterClass(MVT::v2f64, &SystemZ::VR128BitRegClass);
129 }
130
131 if (Subtarget.hasVector())
132 addRegisterClass(MVT::i128, &SystemZ::VR128BitRegClass);
133 }
134
135 // Compute derived properties from the register classes
136 computeRegisterProperties(Subtarget.getRegisterInfo());
137
138 // Set up special registers.
139 setStackPointerRegisterToSaveRestore(Regs->getStackPointerRegister());
140
141 // TODO: It may be better to default to latency-oriented scheduling, however
142 // LLVM's current latency-oriented scheduler can't handle physreg definitions
143 // such as SystemZ has with CC, so set this to the register-pressure
144 // scheduler, because it can.
146
149
151
152 // Instructions are strings of 2-byte aligned 2-byte values.
154 // For performance reasons we prefer 16-byte alignment.
156
157 // Handle operations that are handled in a similar way for all types.
158 for (unsigned I = MVT::FIRST_INTEGER_VALUETYPE;
159 I <= MVT::LAST_FP_VALUETYPE;
160 ++I) {
162 if (isTypeLegal(VT)) {
163 // Lower SET_CC into an IPM-based sequence.
167
168 // Expand SELECT(C, A, B) into SELECT_CC(X, 0, A, B, NE).
170
171 // Lower SELECT_CC and BR_CC into separate comparisons and branches.
174 }
175 }
176
177 // Expand jump table branches as address arithmetic followed by an
178 // indirect jump.
180
181 // Expand BRCOND into a BR_CC (see above).
183
184 // Handle integer types except i128.
185 for (unsigned I = MVT::FIRST_INTEGER_VALUETYPE;
186 I <= MVT::LAST_INTEGER_VALUETYPE;
187 ++I) {
189 if (isTypeLegal(VT) && VT != MVT::i128) {
191
192 // Expand individual DIV and REMs into DIVREMs.
199
200 // Support addition/subtraction with overflow.
203
204 // Support addition/subtraction with carry.
207
208 // Support carry in as value rather than glue.
211
212 // Lower ATOMIC_LOAD_SUB into ATOMIC_LOAD_ADD if LAA and LAAG are
213 // available, or if the operand is constant.
215
216 // Use POPCNT on z196 and above.
217 if (Subtarget.hasPopulationCount())
219 else
221
222 // No special instructions for these.
225
226 // Use *MUL_LOHI where possible instead of MULH*.
231
232 // The fp<=>i32/i64 conversions are all Legal except for f16 and for
233 // unsigned on z10 (only z196 and above have native support for
234 // unsigned conversions).
241 // Handle unsigned 32-bit input types as signed 64-bit types on z10.
242 auto OpAction =
243 (!Subtarget.hasFPExtension() && VT == MVT::i32) ? Promote : Custom;
244 setOperationAction(Op, VT, OpAction);
245 }
246 }
247 }
248
249 // Handle i128 if legal.
250 if (isTypeLegal(MVT::i128)) {
251 // No special instructions for these.
258
259 // We may be able to use VSLDB/VSLD/VSRD for these.
262
263 // No special instructions for these before z17.
264 if (!Subtarget.hasVectorEnhancements3()) {
274 } else {
275 // Even if we do have a legal 128-bit multiply, we do not
276 // want 64-bit multiply-high operations to use it.
279 }
280
281 // Support addition/subtraction with carry.
286
287 // Use VPOPCT and add up partial results.
289
290 // Additional instructions available with z17.
291 if (Subtarget.hasVectorEnhancements3()) {
292 setOperationAction(ISD::ABS, MVT::i128, Legal);
293
295 MVT::i128, Legal);
296 }
297 }
298
299 // These need custom handling in order to handle the f16 conversions.
308
309 // Type legalization will convert 8- and 16-bit atomic operations into
310 // forms that operate on i32s (but still keeping the original memory VT).
311 // Lower them into full i32 operations.
323
324 // Whether or not i128 is not a legal type, we need to custom lower
325 // the atomic operations in order to exploit SystemZ instructions.
330
331 // Mark sign/zero extending atomic loads as legal, which will make
332 // DAGCombiner fold extensions into atomic loads if possible.
334 {MVT::i8, MVT::i16, MVT::i32}, Legal);
336 {MVT::i8, MVT::i16}, Legal);
338 MVT::i8, Legal);
339
340 // We can use the CC result of compare-and-swap to implement
341 // the "success" result of ATOMIC_CMP_SWAP_WITH_SUCCESS.
345
347
348 // Traps are legal, as we will convert them to "j .+2".
349 setOperationAction(ISD::TRAP, MVT::Other, Legal);
350
351 // We have native support for a 64-bit CTLZ, via FLOGR.
355
356 // On z17 we have native support for a 64-bit CTTZ.
357 if (Subtarget.hasMiscellaneousExtensions4()) {
361 }
362
363 // On z15 we have native support for a 64-bit CTPOP.
364 if (Subtarget.hasMiscellaneousExtensions3()) {
367 }
368
369 // Give LowerOperation the chance to replace 64-bit ORs with subregs.
371
372 // Expand 128 bit shifts without using a libcall.
376
377 // Also expand 256 bit shifts if i128 is a legal type.
378 if (isTypeLegal(MVT::i128)) {
382 }
383
384 // Handle bitcast from fp128 to i128.
385 if (!isTypeLegal(MVT::i128))
387
388 // We have native instructions for i8, i16 and i32 extensions, but not i1.
390 for (MVT VT : MVT::integer_valuetypes()) {
394 }
395
396 // Handle the various types of symbolic address.
402
403 // We need to handle dynamic allocations specially because of the
404 // 160-byte area at the bottom of the stack.
407
410
411 // Handle prefetches with PFD or PFDRL.
413
414 // Handle readcyclecounter with STCKF.
416
418 // Assume by default that all vector operations need to be expanded.
419 for (unsigned Opcode = 0; Opcode < ISD::BUILTIN_OP_END; ++Opcode)
420 if (getOperationAction(Opcode, VT) == Legal)
421 setOperationAction(Opcode, VT, Expand);
422
423 // Likewise all truncating stores and extending loads.
424 for (MVT InnerVT : MVT::fixedlen_vector_valuetypes()) {
425 setTruncStoreAction(VT, InnerVT, Expand);
428 setLoadExtAction(ISD::EXTLOAD, VT, InnerVT, Expand);
429 }
430
431 if (isTypeLegal(VT)) {
432 // These operations are legal for anything that can be stored in a
433 // vector register, even if there is no native support for the format
434 // as such. In particular, we can do these for v4f32 even though there
435 // are no specific instructions for that format.
441
442 // Likewise, except that we need to replace the nodes with something
443 // more specific.
446 }
447 }
448
449 // Handle integer vector types.
451 if (isTypeLegal(VT)) {
452 // These operations have direct equivalents.
457 if (VT != MVT::v2i64 || Subtarget.hasVectorEnhancements3()) {
461 }
462 if (Subtarget.hasVectorEnhancements3() &&
463 VT != MVT::v16i8 && VT != MVT::v8i16) {
468 }
473 if (Subtarget.hasVectorEnhancements1())
475 else
479
480 // Convert a GPR scalar to a vector by inserting it into element 0.
482
483 // Use a series of unpacks for extensions.
486
487 // Detect shifts/rotates by a scalar amount and convert them into
488 // V*_BY_SCALAR.
493
494 // Add ISD::VECREDUCE_ADD as custom in order to implement
495 // it with VZERO+VSUM
497
498 // Map SETCCs onto one of VCE, VCH or VCHL, swapping the operands
499 // and inverting the result as necessary.
501
503 Legal);
504 }
505 }
506
507 if (Subtarget.hasVector()) {
508 // There should be no need to check for float types other than v2f64
509 // since <2 x f32> isn't a legal type.
518
527 }
528
529 if (Subtarget.hasVectorEnhancements2()) {
538
547 }
548
549 // Handle floating-point types.
550 if (!useSoftFloat()) {
551 // Promote all f16 operations to float, with some exceptions below.
552 for (unsigned Opc = 0; Opc < ISD::BUILTIN_OP_END; ++Opc)
553 setOperationAction(Opc, MVT::f16, Promote);
555 for (MVT VT : {MVT::f32, MVT::f64, MVT::f128}) {
556 setLoadExtAction(ISD::EXTLOAD, VT, MVT::f16, Expand);
557 setTruncStoreAction(VT, MVT::f16, Expand);
558 }
560 setOperationAction(Op, MVT::f16, Subtarget.hasVector() ? Legal : Custom);
564
565 for (auto Op : {ISD::FNEG, ISD::FABS, ISD::FCOPYSIGN})
566 setOperationAction(Op, MVT::f16, Legal);
567 }
568
569 for (unsigned I = MVT::FIRST_FP_VALUETYPE;
570 I <= MVT::LAST_FP_VALUETYPE;
571 ++I) {
573 if (isTypeLegal(VT) && VT != MVT::f16) {
574 // We can use FI for FRINT.
576
577 // We can use the extended form of FI for other rounding operations.
578 if (Subtarget.hasFPExtension()) {
585 }
586
587 // No special instructions for these.
593
594 // Special treatment.
596
597 // Handle constrained floating-point operations.
606 if (Subtarget.hasFPExtension()) {
613 }
614
615 // Extension from f16 needs libcall.
618 }
619 }
620
621 // Handle floating-point vector types.
622 if (Subtarget.hasVector()) {
623 // Scalar-to-vector conversion is just a subreg.
627
628 // Some insertions and extractions can be done directly but others
629 // need to go via integers.
636
637 // These operations have direct equivalents.
638 setOperationAction(ISD::FADD, MVT::v2f64, Legal);
639 setOperationAction(ISD::FNEG, MVT::v2f64, Legal);
640 setOperationAction(ISD::FSUB, MVT::v2f64, Legal);
641 setOperationAction(ISD::FMUL, MVT::v2f64, Legal);
642 setOperationAction(ISD::FMA, MVT::v2f64, Legal);
643 setOperationAction(ISD::FDIV, MVT::v2f64, Legal);
644 setOperationAction(ISD::FABS, MVT::v2f64, Legal);
645 setOperationAction(ISD::FSQRT, MVT::v2f64, Legal);
646 setOperationAction(ISD::FRINT, MVT::v2f64, Legal);
649 setOperationAction(ISD::FCEIL, MVT::v2f64, Legal);
653
654 // Handle constrained floating-point operations.
668
673 if (Subtarget.hasVectorEnhancements1()) {
676 }
677 }
678
679 // The vector enhancements facility 1 has instructions for these.
680 if (Subtarget.hasVectorEnhancements1()) {
681 setOperationAction(ISD::FADD, MVT::v4f32, Legal);
682 setOperationAction(ISD::FNEG, MVT::v4f32, Legal);
683 setOperationAction(ISD::FSUB, MVT::v4f32, Legal);
684 setOperationAction(ISD::FMUL, MVT::v4f32, Legal);
685 setOperationAction(ISD::FMA, MVT::v4f32, Legal);
686 setOperationAction(ISD::FDIV, MVT::v4f32, Legal);
687 setOperationAction(ISD::FABS, MVT::v4f32, Legal);
688 setOperationAction(ISD::FSQRT, MVT::v4f32, Legal);
689 setOperationAction(ISD::FRINT, MVT::v4f32, Legal);
692 setOperationAction(ISD::FCEIL, MVT::v4f32, Legal);
696
697 for (MVT Type : {MVT::f64, MVT::v2f64, MVT::f32, MVT::v4f32, MVT::f128}) {
706 }
707
708 // Handle constrained floating-point operations.
722 for (auto VT : { MVT::f32, MVT::f64, MVT::f128,
723 MVT::v4f32, MVT::v2f64 }) {
730 }
731 }
732
733 // We only have fused f128 multiply-addition on vector registers.
734 if (!Subtarget.hasVectorEnhancements1()) {
737 }
738
739 // We don't have a copysign instruction on vector registers.
740 if (Subtarget.hasVectorEnhancements1())
742
743 // Needed so that we don't try to implement f128 constant loads using
744 // a load-and-extend of a f80 constant (in cases where the constant
745 // would fit in an f80).
746 for (MVT VT : MVT::fp_valuetypes())
747 setLoadExtAction(ISD::EXTLOAD, VT, MVT::f80, Expand);
748
749 // We don't have extending load instruction on vector registers.
750 if (Subtarget.hasVectorEnhancements1()) {
751 setLoadExtAction(ISD::EXTLOAD, MVT::f128, MVT::f32, Expand);
752 setLoadExtAction(ISD::EXTLOAD, MVT::f128, MVT::f64, Expand);
753 }
754
755 // Floating-point truncation and stores need to be done separately.
756 setTruncStoreAction(MVT::f64, MVT::f32, Expand);
757 setTruncStoreAction(MVT::f128, MVT::f32, Expand);
758 setTruncStoreAction(MVT::f128, MVT::f64, Expand);
759
760 // We have 64-bit FPR<->GPR moves, but need special handling for
761 // 32-bit forms.
762 if (!Subtarget.hasVector()) {
765 }
766
767 // VASTART and VACOPY need to deal with the SystemZ-specific varargs
768 // structure, but VAEND is a no-op.
772
773 if (Subtarget.isTargetzOS()) {
774 // Handle address space casts between mixed sized pointers.
777 }
778
780
781 // Codes for which we want to perform some z-specific combinations.
785 ISD::LOAD,
798 ISD::SRL,
799 ISD::SRA,
800 ISD::MUL,
801 ISD::SDIV,
802 ISD::UDIV,
803 ISD::SREM,
804 ISD::UREM,
807
808 // Handle intrinsics.
811
812 // We're not using SJLJ for exception handling, but they're implemented
813 // solely to support use of __builtin_setjmp / __builtin_longjmp.
816
817 // We want to use MVC in preference to even a single load/store pair.
818 MaxStoresPerMemcpy = Subtarget.hasVector() ? 2 : 0;
820
821 // Same with memmove.
822 MaxStoresPerMemmove = Subtarget.hasVector() ? 2 : 0;
824
825 // The main memset sequence is a byte store followed by an MVC.
826 // Two STC or MV..I stores win over that, but the kind of fused stores
827 // generated by target-independent code don't when the byte value is
828 // variable. E.g. "STC <reg>;MHI <reg>,257;STH <reg>" is not better
829 // than "STC;MVC". Handle the choice in target-specific code instead.
830 MaxStoresPerMemset = Subtarget.hasVector() ? 2 : 0;
832
833 // Default to having -disable-strictnode-mutation on
834 IsStrictFPEnabled = true;
835}
836
838 return Subtarget.hasSoftFloat();
839}
840
842 LLVMContext &Context, CallingConv::ID CC, EVT VT, EVT &IntermediateVT,
843 unsigned &NumIntermediates, MVT &RegisterVT) const {
844 // Pass fp16 vectors in VR(s).
845 if (Subtarget.hasVector() && VT.isVectorOf(MVT::f16)) {
846 IntermediateVT = RegisterVT = MVT::v8f16;
847 return NumIntermediates =
849 }
851 Context, CC, VT, IntermediateVT, NumIntermediates, RegisterVT);
852}
853
856 EVT VT) const {
857 // 128-bit single-element vector types are passed like other vectors,
858 // not like their element type.
859 if (Subtarget.hasVector() && VT.isVector() && VT.getSizeInBits() == 128 &&
860 VT.getVectorNumElements() == 1)
861 return MVT::v16i8;
862 // Pass fp16 vectors in VR(s).
863 if (Subtarget.hasVector() && VT.isVectorOf(MVT::f16))
864 return MVT::v8f16;
865 return TargetLowering::getRegisterTypeForCallingConv(Context, CC, VT);
866}
867
869 LLVMContext &Context, CallingConv::ID CC, EVT VT) const {
870 // Pass fp16 vectors in VR(s).
871 if (Subtarget.hasVector() && VT.isVectorOf(MVT::f16))
873 return TargetLowering::getNumRegistersForCallingConv(Context, CC, VT);
874}
875
877 LLVMContext &, EVT VT) const {
878 if (!VT.isVector())
879 return MVT::i32;
881}
882
884 const MachineFunction &MF, EVT VT) const {
885 if (useSoftFloat())
886 return false;
887
888 VT = VT.getScalarType();
889
890 if (!VT.isSimple())
891 return false;
892
893 switch (VT.getSimpleVT().SimpleTy) {
894 case MVT::f32:
895 case MVT::f64:
896 return true;
897 case MVT::f128:
898 return Subtarget.hasVectorEnhancements1();
899 default:
900 break;
901 }
902
903 return false;
904}
905
906// Return true if the constant can be generated with a vector instruction,
907// such as VGM, VGMB or VREPI.
909 const SystemZSubtarget &Subtarget) {
910 const SystemZInstrInfo *TII = Subtarget.getInstrInfo();
911 if (!Subtarget.hasVector() ||
912 (isFP128 && !Subtarget.hasVectorEnhancements1()))
913 return false;
914
915 // Try using VECTOR GENERATE BYTE MASK. This is the architecturally-
916 // preferred way of creating all-zero and all-one vectors so give it
917 // priority over other methods below.
918 unsigned Mask = 0;
919 unsigned I = 0;
920 for (; I < SystemZ::VectorBytes; ++I) {
921 uint64_t Byte = IntBits.lshr(I * 8).trunc(8).getZExtValue();
922 if (Byte == 0xff)
923 Mask |= 1ULL << I;
924 else if (Byte != 0)
925 break;
926 }
927 if (I == SystemZ::VectorBytes) {
928 Opcode = SystemZISD::BYTE_MASK;
929 OpVals.push_back(Mask);
931 return true;
932 }
933
934 if (SplatBitSize > 64)
935 return false;
936
937 auto TryValue = [&](uint64_t Value) -> bool {
938 // Try VECTOR REPLICATE IMMEDIATE
939 int64_t SignedValue = SignExtend64(Value, SplatBitSize);
940 if (isInt<16>(SignedValue)) {
941 OpVals.push_back(((unsigned) SignedValue));
942 Opcode = SystemZISD::REPLICATE;
944 SystemZ::VectorBits / SplatBitSize);
945 return true;
946 }
947 // Try VECTOR GENERATE MASK
948 unsigned Start, End;
949 if (TII->isRxSBGMask(Value, SplatBitSize, Start, End)) {
950 // isRxSBGMask returns the bit numbers for a full 64-bit value, with 0
951 // denoting 1 << 63 and 63 denoting 1. Convert them to bit numbers for
952 // an SplatBitSize value, so that 0 denotes 1 << (SplatBitSize-1).
953 OpVals.push_back(Start - (64 - SplatBitSize));
954 OpVals.push_back(End - (64 - SplatBitSize));
955 Opcode = SystemZISD::ROTATE_MASK;
957 SystemZ::VectorBits / SplatBitSize);
958 return true;
959 }
960 return false;
961 };
962
963 // First try assuming that any undefined bits above the highest set bit
964 // and below the lowest set bit are 1s. This increases the likelihood of
965 // being able to use a sign-extended element value in VECTOR REPLICATE
966 // IMMEDIATE or a wraparound mask in VECTOR GENERATE MASK.
967 uint64_t SplatBitsZ = SplatBits.getZExtValue();
968 uint64_t SplatUndefZ = SplatUndef.getZExtValue();
969 unsigned LowerBits = llvm::countr_zero(SplatBitsZ);
970 unsigned UpperBits = llvm::countl_zero(SplatBitsZ);
971 uint64_t Lower = SplatUndefZ & maskTrailingOnes<uint64_t>(LowerBits);
972 uint64_t Upper = SplatUndefZ & maskLeadingOnes<uint64_t>(UpperBits);
973 if (TryValue(SplatBitsZ | Upper | Lower))
974 return true;
975
976 // Now try assuming that any undefined bits between the first and
977 // last defined set bits are set. This increases the chances of
978 // using a non-wraparound mask.
979 uint64_t Middle = SplatUndefZ & ~Upper & ~Lower;
980 return TryValue(SplatBitsZ | Middle);
981}
982
984 if (IntImm.isSingleWord()) {
985 IntBits = APInt(128, IntImm.getZExtValue());
986 IntBits <<= (SystemZ::VectorBits - IntImm.getBitWidth());
987 } else
988 IntBits = IntImm;
989 assert(IntBits.getBitWidth() == 128 && "Unsupported APInt.");
990
991 // Find the smallest splat.
992 SplatBits = IntImm;
993 unsigned Width = SplatBits.getBitWidth();
994 while (Width > 8) {
995 unsigned HalfSize = Width / 2;
996 APInt HighValue = SplatBits.lshr(HalfSize).trunc(HalfSize);
997 APInt LowValue = SplatBits.trunc(HalfSize);
998
999 // If the two halves do not match, stop here.
1000 if (HighValue != LowValue || 8 > HalfSize)
1001 break;
1002
1003 SplatBits = HighValue;
1004 Width = HalfSize;
1005 }
1006 SplatUndef = 0;
1007 SplatBitSize = Width;
1008}
1009
1011 assert(BVN->isConstant() && "Expected a constant BUILD_VECTOR");
1012 bool HasAnyUndefs;
1013
1014 // Get IntBits by finding the 128 bit splat.
1015 BVN->isConstantSplat(IntBits, SplatUndef, SplatBitSize, HasAnyUndefs, 128,
1016 true);
1017
1018 // Get SplatBits by finding the 8 bit or greater splat.
1019 BVN->isConstantSplat(SplatBits, SplatUndef, SplatBitSize, HasAnyUndefs, 8,
1020 true);
1021}
1022
1024 bool ForCodeSize) const {
1025 // We can load zero using LZ?R and negative zero using LZ?R;LC?BR.
1026 if (Imm.isZero() || Imm.isNegZero())
1027 return true;
1028
1030}
1031
1034 MachineBasicBlock *MBB) const {
1035 DebugLoc DL = MI.getDebugLoc();
1036 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
1037 const SystemZRegisterInfo *TRI = Subtarget.getRegisterInfo();
1038
1039 MachineFunction *MF = MBB->getParent();
1040 MachineRegisterInfo &MRI = MF->getRegInfo();
1041
1042 const BasicBlock *BB = MBB->getBasicBlock();
1043 MachineFunction::iterator I = ++MBB->getIterator();
1044
1045 Register DstReg = MI.getOperand(0).getReg();
1046 const TargetRegisterClass *RC = MRI.getRegClass(DstReg);
1047 assert(TRI->isTypeLegalForClass(*RC, MVT::i32) && "Invalid destination!");
1048 (void)TRI;
1049 Register MainDstReg = MRI.createVirtualRegister(RC);
1050 Register RestoreDstReg = MRI.createVirtualRegister(RC);
1051
1052 MVT PVT = getPointerTy(MF->getDataLayout());
1053 assert((PVT == MVT::i64 || PVT == MVT::i32) && "Invalid Pointer Size!");
1054 // For v = setjmp(buf), we generate.
1055 // Algorithm:
1056 //
1057 // ---------
1058 // | thisMBB |
1059 // ---------
1060 // |
1061 // ------------------------
1062 // | |
1063 // ---------- ---------------
1064 // | mainMBB | | restoreMBB |
1065 // | v = 0 | | v = 1 |
1066 // ---------- ---------------
1067 // | |
1068 // -------------------------
1069 // |
1070 // -----------------------------
1071 // | sinkMBB |
1072 // | phi(v_mainMBB,v_restoreMBB) |
1073 // -----------------------------
1074 // thisMBB:
1075 // buf[FPOffset] = Frame Pointer if hasFP.
1076 // buf[LabelOffset] = restoreMBB <-- takes address of restoreMBB.
1077 // buf[BCOffset] = Backchain value if building with -mbackchain.
1078 // buf[SPOffset] = Stack Pointer.
1079 // buf[LPOffset] = We never write this slot with R13, gcc stores R13 always.
1080 // SjLjSetup restoreMBB
1081 // mainMBB:
1082 // v_main = 0
1083 // sinkMBB:
1084 // v = phi(v_main, v_restore)
1085 // restoreMBB:
1086 // v_restore = 1
1087
1088 MachineBasicBlock *ThisMBB = MBB;
1089 MachineBasicBlock *MainMBB = MF->CreateMachineBasicBlock(BB);
1090 MachineBasicBlock *SinkMBB = MF->CreateMachineBasicBlock(BB);
1091 MachineBasicBlock *RestoreMBB = MF->CreateMachineBasicBlock(BB);
1092
1093 MF->insert(I, MainMBB);
1094 MF->insert(I, SinkMBB);
1095 MF->push_back(RestoreMBB);
1096 RestoreMBB->setMachineBlockAddressTaken();
1097
1099
1100 // Transfer the remainder of BB and its successor edges to sinkMBB.
1101 SinkMBB->splice(SinkMBB->begin(), MBB,
1102 std::next(MachineBasicBlock::iterator(MI)), MBB->end());
1104
1105 // thisMBB:
1106 const int64_t FPOffset = 0; // Slot 1.
1107 const int64_t LabelOffset = 1 * PVT.getStoreSize(); // Slot 2.
1108 const int64_t BCOffset = 2 * PVT.getStoreSize(); // Slot 3.
1109 const int64_t SPOffset = 3 * PVT.getStoreSize(); // Slot 4.
1110
1111 // Buf address.
1112 Register BufReg = MI.getOperand(1).getReg();
1113
1114 const TargetRegisterClass *PtrRC = getRegClassFor(PVT);
1115 Register LabelReg = MRI.createVirtualRegister(PtrRC);
1116
1117 // Prepare IP for longjmp.
1118 BuildMI(*ThisMBB, MI, DL, TII->get(SystemZ::LARL), LabelReg)
1119 .addMBB(RestoreMBB);
1120 // Store IP for return from jmp, slot 2, offset = 1.
1121 BuildMI(*ThisMBB, MI, DL, TII->get(SystemZ::STG))
1122 .addReg(LabelReg)
1123 .addReg(BufReg)
1124 .addImm(LabelOffset)
1125 .addReg(0);
1126
1127 auto *SpecialRegs = Subtarget.getSpecialRegisters();
1128 bool HasFP = Subtarget.getFrameLowering()->hasFP(*MF);
1129 if (HasFP) {
1130 BuildMI(*ThisMBB, MI, DL, TII->get(SystemZ::STG))
1131 .addReg(SpecialRegs->getFramePointerRegister())
1132 .addReg(BufReg)
1133 .addImm(FPOffset)
1134 .addReg(0);
1135 }
1136
1137 // Store SP.
1138 BuildMI(*ThisMBB, MI, DL, TII->get(SystemZ::STG))
1139 .addReg(SpecialRegs->getStackPointerRegister())
1140 .addReg(BufReg)
1141 .addImm(SPOffset)
1142 .addReg(0);
1143
1144 // Slot 3(Offset = 2) Backchain value (if building with -mbackchain).
1145 bool BackChain = MF->getSubtarget<SystemZSubtarget>().hasBackChain();
1146 if (BackChain) {
1147 Register BCReg = MRI.createVirtualRegister(PtrRC);
1148 auto *TFL = Subtarget.getFrameLowering<SystemZFrameLowering>();
1149 MIB = BuildMI(*ThisMBB, MI, DL, TII->get(SystemZ::LG), BCReg)
1150 .addReg(SpecialRegs->getStackPointerRegister())
1151 .addImm(TFL->getBackchainOffset(*MF))
1152 .addReg(0);
1153
1154 BuildMI(*ThisMBB, MI, DL, TII->get(SystemZ::STG))
1155 .addReg(BCReg)
1156 .addReg(BufReg)
1157 .addImm(BCOffset)
1158 .addReg(0);
1159 }
1160
1161 // Setup.
1162 MIB = BuildMI(*ThisMBB, MI, DL, TII->get(SystemZ::EH_SjLj_Setup))
1163 .addMBB(RestoreMBB);
1164
1165 const SystemZRegisterInfo *RegInfo = Subtarget.getRegisterInfo();
1166 MIB.addRegMask(RegInfo->getNoPreservedMask());
1167
1168 ThisMBB->addSuccessor(MainMBB);
1169 ThisMBB->addSuccessor(RestoreMBB);
1170
1171 // mainMBB:
1172 BuildMI(MainMBB, DL, TII->get(SystemZ::LHI), MainDstReg).addImm(0);
1173 MainMBB->addSuccessor(SinkMBB);
1174
1175 // sinkMBB:
1176 BuildMI(*SinkMBB, SinkMBB->begin(), DL, TII->get(SystemZ::PHI), DstReg)
1177 .addReg(MainDstReg)
1178 .addMBB(MainMBB)
1179 .addReg(RestoreDstReg)
1180 .addMBB(RestoreMBB);
1181
1182 // restoreMBB.
1183 BuildMI(RestoreMBB, DL, TII->get(SystemZ::LHI), RestoreDstReg).addImm(1);
1184 BuildMI(RestoreMBB, DL, TII->get(SystemZ::J)).addMBB(SinkMBB);
1185 RestoreMBB->addSuccessor(SinkMBB);
1186
1187 MI.eraseFromParent();
1188
1189 return SinkMBB;
1190}
1191
1194 MachineBasicBlock *MBB) const {
1195
1196 DebugLoc DL = MI.getDebugLoc();
1197 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
1198
1199 MachineFunction *MF = MBB->getParent();
1200 MachineRegisterInfo &MRI = MF->getRegInfo();
1201
1202 MVT PVT = getPointerTy(MF->getDataLayout());
1203 assert((PVT == MVT::i64 || PVT == MVT::i32) && "Invalid Pointer Size!");
1204 Register BufReg = MI.getOperand(0).getReg();
1205 const TargetRegisterClass *RC = MRI.getRegClass(BufReg);
1206 auto *SpecialRegs = Subtarget.getSpecialRegisters();
1207
1208 Register Tmp = MRI.createVirtualRegister(RC);
1209 Register BCReg = MRI.createVirtualRegister(RC);
1210
1212
1213 const int64_t FPOffset = 0;
1214 const int64_t LabelOffset = 1 * PVT.getStoreSize();
1215 const int64_t BCOffset = 2 * PVT.getStoreSize();
1216 const int64_t SPOffset = 3 * PVT.getStoreSize();
1217 const int64_t LPOffset = 4 * PVT.getStoreSize();
1218
1219 MIB = BuildMI(*MBB, MI, DL, TII->get(SystemZ::LG), Tmp)
1220 .addReg(BufReg)
1221 .addImm(LabelOffset)
1222 .addReg(0);
1223
1224 MIB = BuildMI(*MBB, MI, DL, TII->get(SystemZ::LG),
1225 SpecialRegs->getFramePointerRegister())
1226 .addReg(BufReg)
1227 .addImm(FPOffset)
1228 .addReg(0);
1229
1230 // We are restoring R13 even though we never stored in setjmp from llvm,
1231 // as gcc always stores R13 in builtin_setjmp. We could have mixed code
1232 // gcc setjmp and llvm longjmp.
1233 MIB = BuildMI(*MBB, MI, DL, TII->get(SystemZ::LG), SystemZ::R13D)
1234 .addReg(BufReg)
1235 .addImm(LPOffset)
1236 .addReg(0);
1237
1238 bool BackChain = MF->getSubtarget<SystemZSubtarget>().hasBackChain();
1239 if (BackChain) {
1240 MIB = BuildMI(*MBB, MI, DL, TII->get(SystemZ::LG), BCReg)
1241 .addReg(BufReg)
1242 .addImm(BCOffset)
1243 .addReg(0);
1244 }
1245
1246 MIB = BuildMI(*MBB, MI, DL, TII->get(SystemZ::LG),
1247 SpecialRegs->getStackPointerRegister())
1248 .addReg(BufReg)
1249 .addImm(SPOffset)
1250 .addReg(0);
1251
1252 if (BackChain) {
1253 auto *TFL = Subtarget.getFrameLowering<SystemZFrameLowering>();
1254 BuildMI(*MBB, MI, DL, TII->get(SystemZ::STG))
1255 .addReg(BCReg)
1256 .addReg(SpecialRegs->getStackPointerRegister())
1257 .addImm(TFL->getBackchainOffset(*MF))
1258 .addReg(0);
1259 }
1260
1261 MIB = BuildMI(*MBB, MI, DL, TII->get(SystemZ::BR)).addReg(Tmp);
1262
1263 MI.eraseFromParent();
1264 return MBB;
1265}
1266
1267/// Returns true if stack probing through inline assembly is requested.
1269 // If the function specifically requests inline stack probes, emit them.
1270 if (MF.getFunction().hasFnAttribute("probe-stack"))
1271 return MF.getFunction().getFnAttribute("probe-stack").getValueAsString() ==
1272 "inline-asm";
1273 return false;
1274}
1275
1280
1285
1288 const AtomicRMWInst *RMW) const {
1289 // Don't expand subword operations as they require special treatment.
1290 if (RMW->getType()->isIntegerTy(8) || RMW->getType()->isIntegerTy(16))
1292
1293 // Don't expand if there is a target instruction available.
1294 if (Subtarget.hasInterlockedAccess1() &&
1295 (RMW->getType()->isIntegerTy(32) || RMW->getType()->isIntegerTy(64)) &&
1302
1304}
1305
1307 // We can use CGFI or CLGFI.
1308 return isInt<32>(Imm) || isUInt<32>(Imm);
1309}
1310
1312 // We can use ALGFI or SLGFI.
1313 return isUInt<32>(Imm) || isUInt<32>(-Imm);
1314}
1315
1317 EVT VT, unsigned, Align, MachineMemOperand::Flags, unsigned *Fast) const {
1318 // Unaligned accesses should never be slower than the expanded version.
1319 // We check specifically for aligned accesses in the few cases where
1320 // they are required.
1321 if (Fast)
1322 *Fast = 1;
1323 return true;
1324}
1325
1327 EVT VT = Y.getValueType();
1328
1329 // We can use NC(G)RK for types in GPRs ...
1330 if (VT == MVT::i32 || VT == MVT::i64)
1331 return Subtarget.hasMiscellaneousExtensions3();
1332
1333 // ... or VNC for types in VRs.
1334 if (VT.isVector() || VT == MVT::i128)
1335 return Subtarget.hasVector();
1336
1337 return false;
1338}
1339
1340// Information about the addressing mode for a memory access.
1342 // True if a long displacement is supported.
1344
1345 // True if use of index register is supported.
1347
1348 AddressingMode(bool LongDispl, bool IdxReg) :
1349 LongDisplacement(LongDispl), IndexReg(IdxReg) {}
1350};
1351
1352// Return the desired addressing mode for a Load which has only one use (in
1353// the same block) which is a Store.
1355 Type *Ty) {
1356 // With vector support a Load->Store combination may be combined to either
1357 // an MVC or vector operations and it seems to work best to allow the
1358 // vector addressing mode.
1359 if (HasVector)
1360 return AddressingMode(false/*LongDispl*/, true/*IdxReg*/);
1361
1362 // Otherwise only the MVC case is special.
1363 bool MVC = Ty->isIntegerTy(8);
1364 return AddressingMode(!MVC/*LongDispl*/, !MVC/*IdxReg*/);
1365}
1366
1367// Return the addressing mode which seems most desirable given an LLVM
1368// Instruction pointer.
1369static AddressingMode
1372 switch (II->getIntrinsicID()) {
1373 default: break;
1374 case Intrinsic::memset:
1375 case Intrinsic::memmove:
1376 case Intrinsic::memcpy:
1377 return AddressingMode(false/*LongDispl*/, false/*IdxReg*/);
1378 }
1379 }
1380
1381 if (isa<LoadInst>(I) && I->hasOneUse()) {
1382 auto *SingleUser = cast<Instruction>(*I->user_begin());
1383 if (SingleUser->getParent() == I->getParent()) {
1384 if (isa<ICmpInst>(SingleUser)) {
1385 if (auto *C = dyn_cast<ConstantInt>(SingleUser->getOperand(1)))
1386 if (C->getBitWidth() <= 64 &&
1387 (isInt<16>(C->getSExtValue()) || isUInt<16>(C->getZExtValue())))
1388 // Comparison of memory with 16 bit signed / unsigned immediate
1389 return AddressingMode(false/*LongDispl*/, false/*IdxReg*/);
1390 } else if (isa<StoreInst>(SingleUser))
1391 // Load->Store
1392 return getLoadStoreAddrMode(HasVector, I->getType());
1393 }
1394 } else if (auto *StoreI = dyn_cast<StoreInst>(I)) {
1395 if (auto *LoadI = dyn_cast<LoadInst>(StoreI->getValueOperand()))
1396 if (LoadI->hasOneUse() && LoadI->getParent() == I->getParent())
1397 // Load->Store
1398 return getLoadStoreAddrMode(HasVector, LoadI->getType());
1399 }
1400
1401 if (HasVector && (isa<LoadInst>(I) || isa<StoreInst>(I))) {
1402
1403 // * Use LDE instead of LE/LEY for z13 to avoid partial register
1404 // dependencies (LDE only supports small offsets).
1405 // * Utilize the vector registers to hold floating point
1406 // values (vector load / store instructions only support small
1407 // offsets).
1408
1409 Type *MemAccessTy = (isa<LoadInst>(I) ? I->getType() :
1410 I->getOperand(0)->getType());
1411 bool IsFPAccess = MemAccessTy->isFloatingPointTy();
1412 bool IsVectorAccess = MemAccessTy->isVectorTy();
1413
1414 // A store of an extracted vector element will be combined into a VSTE type
1415 // instruction.
1416 if (!IsVectorAccess && isa<StoreInst>(I)) {
1417 Value *DataOp = I->getOperand(0);
1418 if (isa<ExtractElementInst>(DataOp))
1419 IsVectorAccess = true;
1420 }
1421
1422 // A load which gets inserted into a vector element will be combined into a
1423 // VLE type instruction.
1424 if (!IsVectorAccess && isa<LoadInst>(I) && I->hasOneUse()) {
1425 User *LoadUser = *I->user_begin();
1426 if (isa<InsertElementInst>(LoadUser))
1427 IsVectorAccess = true;
1428 }
1429
1430 if (IsFPAccess || IsVectorAccess)
1431 return AddressingMode(false/*LongDispl*/, true/*IdxReg*/);
1432 }
1433
1434 return AddressingMode(true/*LongDispl*/, true/*IdxReg*/);
1435}
1436
1438 const AddrMode &AM, Type *Ty, unsigned AS, Instruction *I) const {
1439 // Punt on globals for now, although they can be used in limited
1440 // RELATIVE LONG cases.
1441 if (AM.BaseGV)
1442 return false;
1443
1444 // Require a 20-bit signed offset.
1445 if (!isInt<20>(AM.BaseOffs))
1446 return false;
1447
1448 bool RequireD12 =
1449 Subtarget.hasVector() && (Ty->isVectorTy() || Ty->isIntegerTy(128));
1450 AddressingMode SupportedAM(!RequireD12, true);
1451 if (I != nullptr)
1452 SupportedAM = supportedAddressingMode(I, Subtarget.hasVector());
1453
1454 if (!SupportedAM.LongDisplacement && !isUInt<12>(AM.BaseOffs))
1455 return false;
1456
1457 if (!SupportedAM.IndexReg)
1458 // No indexing allowed.
1459 return AM.Scale == 0;
1460 else
1461 // Indexing is OK but no scale factor can be applied.
1462 return AM.Scale == 0 || AM.Scale == 1;
1463}
1464
1466 LLVMContext &Context, std::vector<EVT> &MemOps, unsigned Limit,
1467 const MemOp &Op, unsigned DstAS, unsigned SrcAS,
1468 const AttributeList &FuncAttributes, EVT *LargestVT) const {
1469
1470 assert(Limit != ~0U &&
1471 "Expected EmitTargetCodeForMemXXX() to handle AlwaysInline cases.");
1472
1473 if (Op.isZeroMemset())
1474 return false; // Memset zero: Use XC.
1475
1476 const int MVCFastLen = 16;
1477 // Use MVC up to 16 bytes for memcpy. Small memset uses STC/MVI for first
1478 // byte.
1479 if (Op.isMemcpy() && Op.size() <= MVCFastLen)
1480 return false;
1481 if (Op.isMemset() && Op.size() - 1 <= MVCFastLen)
1482 return false;
1483
1484 // Avoid unaligned VL/VST:s.
1485 if ((Op.size() >= 16 && !Op.isAligned(Align(8))) ||
1486 (Op.size() >= 25 && Op.size() <= 31))
1487 return false;
1488
1490 Context, MemOps, Limit, Op, DstAS, SrcAS, FuncAttributes, LargestVT);
1491}
1492
1494 LLVMContext &Context, const MemOp &Op,
1495 const AttributeList &FuncAttributes) const {
1496 return Subtarget.hasVector() ? MVT::v2i64 : MVT::Other;
1497}
1498
1499bool SystemZTargetLowering::isTruncateFree(Type *FromType, Type *ToType) const {
1500 if (!FromType->isIntegerTy() || !ToType->isIntegerTy())
1501 return false;
1502 unsigned FromBits = FromType->getPrimitiveSizeInBits().getFixedValue();
1503 unsigned ToBits = ToType->getPrimitiveSizeInBits().getFixedValue();
1504 return FromBits > ToBits;
1505}
1506
1508 if (!FromVT.isInteger() || !ToVT.isInteger())
1509 return false;
1510 unsigned FromBits = FromVT.getFixedSizeInBits();
1511 unsigned ToBits = ToVT.getFixedSizeInBits();
1512 return FromBits > ToBits;
1513}
1514
1515//===----------------------------------------------------------------------===//
1516// Inline asm support
1517//===----------------------------------------------------------------------===//
1518
1521 if (Constraint.size() == 1) {
1522 switch (Constraint[0]) {
1523 case 'a': // Address register
1524 case 'd': // Data register (equivalent to 'r')
1525 case 'f': // Floating-point register
1526 case 'h': // High-part register
1527 case 'r': // General-purpose register
1528 case 'v': // Vector register
1529 return C_RegisterClass;
1530
1531 case 'Q': // Memory with base and unsigned 12-bit displacement
1532 case 'R': // Likewise, plus an index
1533 case 'S': // Memory with base and signed 20-bit displacement
1534 case 'T': // Likewise, plus an index
1535 case 'm': // Equivalent to 'T'.
1536 return C_Memory;
1537
1538 case 'I': // Unsigned 8-bit constant
1539 case 'J': // Unsigned 12-bit constant
1540 case 'K': // Signed 16-bit constant
1541 case 'L': // Signed 20-bit displacement (on all targets we support)
1542 case 'M': // 0x7fffffff
1543 return C_Immediate;
1544
1545 default:
1546 break;
1547 }
1548 } else if (Constraint.size() == 2 && Constraint[0] == 'Z') {
1549 switch (Constraint[1]) {
1550 case 'Q': // Address with base and unsigned 12-bit displacement
1551 case 'R': // Likewise, plus an index
1552 case 'S': // Address with base and signed 20-bit displacement
1553 case 'T': // Likewise, plus an index
1554 return C_Address;
1555
1556 default:
1557 break;
1558 }
1559 } else if (Constraint.size() == 5 && Constraint.starts_with("{")) {
1560 if (StringRef("{@cc}").compare(Constraint) == 0)
1561 return C_Other;
1562 }
1563 return TargetLowering::getConstraintType(Constraint);
1564}
1565
1568 AsmOperandInfo &Info, const char *Constraint) const {
1570 Value *CallOperandVal = Info.CallOperandVal;
1571 // If we don't have a value, we can't do a match,
1572 // but allow it at the lowest weight.
1573 if (!CallOperandVal)
1574 return CW_Default;
1575 Type *type = CallOperandVal->getType();
1576 // Look at the constraint type.
1577 switch (*Constraint) {
1578 default:
1579 Weight = TargetLowering::getSingleConstraintMatchWeight(Info, Constraint);
1580 break;
1581
1582 case 'a': // Address register
1583 case 'd': // Data register (equivalent to 'r')
1584 case 'h': // High-part register
1585 case 'r': // General-purpose register
1586 Weight =
1587 CallOperandVal->getType()->isIntegerTy() ? CW_Register : CW_Default;
1588 break;
1589
1590 case 'f': // Floating-point register
1591 if (!useSoftFloat())
1592 Weight = type->isFloatingPointTy() ? CW_Register : CW_Default;
1593 break;
1594
1595 case 'v': // Vector register
1596 if (Subtarget.hasVector())
1597 Weight = (type->isVectorTy() || type->isFloatingPointTy()) ? CW_Register
1598 : CW_Default;
1599 break;
1600
1601 case 'I': // Unsigned 8-bit constant
1602 if (auto *C = dyn_cast<ConstantInt>(CallOperandVal))
1603 if (isUInt<8>(C->getZExtValue()))
1604 Weight = CW_Constant;
1605 break;
1606
1607 case 'J': // Unsigned 12-bit constant
1608 if (auto *C = dyn_cast<ConstantInt>(CallOperandVal))
1609 if (isUInt<12>(C->getZExtValue()))
1610 Weight = CW_Constant;
1611 break;
1612
1613 case 'K': // Signed 16-bit constant
1614 if (auto *C = dyn_cast<ConstantInt>(CallOperandVal))
1615 if (isInt<16>(C->getSExtValue()))
1616 Weight = CW_Constant;
1617 break;
1618
1619 case 'L': // Signed 20-bit displacement (on all targets we support)
1620 if (auto *C = dyn_cast<ConstantInt>(CallOperandVal))
1621 if (isInt<20>(C->getSExtValue()))
1622 Weight = CW_Constant;
1623 break;
1624
1625 case 'M': // 0x7fffffff
1626 if (auto *C = dyn_cast<ConstantInt>(CallOperandVal))
1627 if (C->getZExtValue() == 0x7fffffff)
1628 Weight = CW_Constant;
1629 break;
1630 }
1631 return Weight;
1632}
1633
1634// Parse a "{tNNN}" register constraint for which the register type "t"
1635// has already been verified. MC is the class associated with "t" and
1636// Map maps 0-based register numbers to LLVM register numbers.
1637static std::pair<unsigned, const TargetRegisterClass *>
1639 const unsigned *Map, unsigned Size) {
1640 assert(*(Constraint.end()-1) == '}' && "Missing '}'");
1641 if (isdigit(Constraint[2])) {
1642 unsigned Index;
1643 bool Failed =
1644 Constraint.slice(2, Constraint.size() - 1).getAsInteger(10, Index);
1645 if (!Failed && Index < Size && Map[Index])
1646 return std::make_pair(Map[Index], RC);
1647 }
1648 return std::make_pair(0U, nullptr);
1649}
1650
1651std::pair<unsigned, const TargetRegisterClass *>
1653 const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const {
1654 if (Constraint.size() == 1) {
1655 // GCC Constraint Letters
1656 switch (Constraint[0]) {
1657 default: break;
1658 case 'd': // Data register (equivalent to 'r')
1659 case 'r': // General-purpose register
1660 if (VT.getSizeInBits() == 64)
1661 return std::make_pair(0U, &SystemZ::GR64BitRegClass);
1662 else if (VT.getSizeInBits() == 128)
1663 return std::make_pair(0U, &SystemZ::GR128BitRegClass);
1664 return std::make_pair(0U, &SystemZ::GR32BitRegClass);
1665
1666 case 'a': // Address register
1667 if (VT == MVT::i64)
1668 return std::make_pair(0U, &SystemZ::ADDR64BitRegClass);
1669 else if (VT == MVT::i128)
1670 return std::make_pair(0U, &SystemZ::ADDR128BitRegClass);
1671 return std::make_pair(0U, &SystemZ::ADDR32BitRegClass);
1672
1673 case 'h': // High-part register (an LLVM extension)
1674 return std::make_pair(0U, &SystemZ::GRH32BitRegClass);
1675
1676 case 'f': // Floating-point register
1677 if (!useSoftFloat()) {
1678 if (VT.getSizeInBits() == 16)
1679 return std::make_pair(0U, &SystemZ::FP16BitRegClass);
1680 else if (VT.getSizeInBits() == 64)
1681 return std::make_pair(0U, &SystemZ::FP64BitRegClass);
1682 else if (VT.getSizeInBits() == 128)
1683 return std::make_pair(0U, &SystemZ::FP128BitRegClass);
1684 return std::make_pair(0U, &SystemZ::FP32BitRegClass);
1685 }
1686 break;
1687
1688 case 'v': // Vector register
1689 if (Subtarget.hasVector()) {
1690 if (VT.getSizeInBits() == 16)
1691 return std::make_pair(0U, &SystemZ::VR16BitRegClass);
1692 if (VT.getSizeInBits() == 32)
1693 return std::make_pair(0U, &SystemZ::VR32BitRegClass);
1694 if (VT.getSizeInBits() == 64)
1695 return std::make_pair(0U, &SystemZ::VR64BitRegClass);
1696 return std::make_pair(0U, &SystemZ::VR128BitRegClass);
1697 }
1698 break;
1699 }
1700 }
1701 if (Constraint.starts_with("{")) {
1702
1703 // A clobber constraint (e.g. ~{f0}) will have MVT::Other which is illegal
1704 // to check the size on.
1705 auto getVTSizeInBits = [&VT]() {
1706 return VT == MVT::Other ? 0 : VT.getSizeInBits();
1707 };
1708
1709 // We need to override the default register parsing for GPRs and FPRs
1710 // because the interpretation depends on VT. The internal names of
1711 // the registers are also different from the external names
1712 // (F0D and F0S instead of F0, etc.).
1713 if (Constraint[1] == 'r') {
1714 if (getVTSizeInBits() == 32)
1715 return parseRegisterNumber(Constraint, &SystemZ::GR32BitRegClass,
1717 if (getVTSizeInBits() == 128)
1718 return parseRegisterNumber(Constraint, &SystemZ::GR128BitRegClass,
1720 return parseRegisterNumber(Constraint, &SystemZ::GR64BitRegClass,
1722 }
1723 if (Constraint[1] == 'f') {
1724 if (useSoftFloat())
1725 return std::make_pair(
1726 0u, static_cast<const TargetRegisterClass *>(nullptr));
1727 if (getVTSizeInBits() == 16)
1728 return parseRegisterNumber(Constraint, &SystemZ::FP16BitRegClass,
1730 if (getVTSizeInBits() == 32)
1731 return parseRegisterNumber(Constraint, &SystemZ::FP32BitRegClass,
1733 if (getVTSizeInBits() == 128)
1734 return parseRegisterNumber(Constraint, &SystemZ::FP128BitRegClass,
1736 return parseRegisterNumber(Constraint, &SystemZ::FP64BitRegClass,
1738 }
1739 if (Constraint[1] == 'v') {
1740 if (!Subtarget.hasVector())
1741 return std::make_pair(
1742 0u, static_cast<const TargetRegisterClass *>(nullptr));
1743 if (getVTSizeInBits() == 16)
1744 return parseRegisterNumber(Constraint, &SystemZ::VR16BitRegClass,
1746 if (getVTSizeInBits() == 32)
1747 return parseRegisterNumber(Constraint, &SystemZ::VR32BitRegClass,
1749 if (getVTSizeInBits() == 64)
1750 return parseRegisterNumber(Constraint, &SystemZ::VR64BitRegClass,
1752 return parseRegisterNumber(Constraint, &SystemZ::VR128BitRegClass,
1754 }
1755 if (Constraint[1] == '@') {
1756 if (StringRef("{@cc}").compare(Constraint) == 0)
1757 return std::make_pair(SystemZ::CC, &SystemZ::CCRRegClass);
1758 }
1759 }
1760 return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT);
1761}
1762
1763// FIXME? Maybe this could be a TableGen attribute on some registers and
1764// this table could be generated automatically from RegInfo.
1767 const MachineFunction &MF) const {
1768 Register Reg =
1770 .Case("r4", Subtarget.isTargetXPLINK64() ? SystemZ::R4D
1771 : SystemZ::NoRegister)
1772 .Case("r15",
1773 Subtarget.isTargetELF() ? SystemZ::R15D : SystemZ::NoRegister)
1774 .Default(Register());
1775
1776 return Reg;
1777}
1778
1780 ExceptionHandling EH, const Constant *PersonalityFn) const {
1781 return Subtarget.isTargetXPLINK64() ? SystemZ::R1D : SystemZ::R6D;
1782}
1783
1785 ExceptionHandling EH, const Constant *PersonalityFn) const {
1786 return Subtarget.isTargetXPLINK64() ? SystemZ::R2D : SystemZ::R7D;
1787}
1788
1789// Convert condition code in CCReg to an i32 value.
1791 SDLoc DL(CCReg);
1792 SDValue IPM = DAG.getNode(SystemZISD::IPM, DL, MVT::i32, CCReg);
1793 return DAG.getNode(ISD::SRL, DL, MVT::i32, IPM,
1794 DAG.getConstant(SystemZ::IPM_CC, DL, MVT::i32));
1795}
1796
1797// Lower @cc targets via setcc.
1799 SDValue &Chain, SDValue &Glue, const SDLoc &DL,
1800 const AsmOperandInfo &OpInfo, SelectionDAG &DAG) const {
1801 if (StringRef("{@cc}").compare(OpInfo.ConstraintCode) != 0)
1802 return SDValue();
1803
1804 // Check that return type is valid.
1805 if (OpInfo.ConstraintVT.isVector() || !OpInfo.ConstraintVT.isInteger() ||
1806 OpInfo.ConstraintVT.getSizeInBits() < 8)
1807 report_fatal_error("Glue output operand is of invalid type");
1808
1809 if (Glue.getNode()) {
1810 Glue = DAG.getCopyFromReg(Chain, DL, SystemZ::CC, MVT::i32, Glue);
1811 Chain = Glue.getValue(1);
1812 } else
1813 Glue = DAG.getCopyFromReg(Chain, DL, SystemZ::CC, MVT::i32);
1814 return getCCResult(DAG, Glue);
1815}
1816
1818 SDValue Op, StringRef Constraint, std::vector<SDValue> &Ops,
1819 SelectionDAG &DAG) const {
1820 // Only support length 1 constraints for now.
1821 if (Constraint.size() == 1) {
1822 switch (Constraint[0]) {
1823 case 'I': // Unsigned 8-bit constant
1824 if (auto *C = dyn_cast<ConstantSDNode>(Op))
1825 if (isUInt<8>(C->getZExtValue()))
1826 Ops.push_back(DAG.getTargetConstant(C->getZExtValue(), SDLoc(Op),
1827 Op.getValueType()));
1828 return;
1829
1830 case 'J': // Unsigned 12-bit constant
1831 if (auto *C = dyn_cast<ConstantSDNode>(Op))
1832 if (isUInt<12>(C->getZExtValue()))
1833 Ops.push_back(DAG.getTargetConstant(C->getZExtValue(), SDLoc(Op),
1834 Op.getValueType()));
1835 return;
1836
1837 case 'K': // Signed 16-bit constant
1838 if (auto *C = dyn_cast<ConstantSDNode>(Op))
1839 if (isInt<16>(C->getSExtValue()))
1840 Ops.push_back(DAG.getSignedTargetConstant(
1841 C->getSExtValue(), SDLoc(Op), Op.getValueType()));
1842 return;
1843
1844 case 'L': // Signed 20-bit displacement (on all targets we support)
1845 if (auto *C = dyn_cast<ConstantSDNode>(Op))
1846 if (isInt<20>(C->getSExtValue()))
1847 Ops.push_back(DAG.getSignedTargetConstant(
1848 C->getSExtValue(), SDLoc(Op), Op.getValueType()));
1849 return;
1850
1851 case 'M': // 0x7fffffff
1852 if (auto *C = dyn_cast<ConstantSDNode>(Op))
1853 if (C->getZExtValue() == 0x7fffffff)
1854 Ops.push_back(DAG.getTargetConstant(C->getZExtValue(), SDLoc(Op),
1855 Op.getValueType()));
1856 return;
1857 }
1858 }
1860}
1861
1862//===----------------------------------------------------------------------===//
1863// Calling conventions
1864//===----------------------------------------------------------------------===//
1865
1866#define GET_CALLING_CONV_IMPL
1867#include "SystemZGenCallingConv.inc"
1868
1870 CallingConv::ID) const {
1871 static const MCPhysReg ScratchRegs[] = { SystemZ::R0D, SystemZ::R1D,
1872 SystemZ::R14D, 0 };
1873 return ScratchRegs;
1874}
1875
1877 Type *ToType) const {
1878 return isTruncateFree(FromType, ToType);
1879}
1880
1882 return CI->isTailCall();
1883}
1884
1885// Value is a value that has been passed to us in the location described by VA
1886// (and so has type VA.getLocVT()). Convert Value to VA.getValVT(), chaining
1887// any loads onto Chain.
1889 CCValAssign &VA, SDValue Chain,
1890 SDValue Value) {
1891 // If the argument has been promoted from a smaller type, insert an
1892 // assertion to capture this.
1893 if (VA.getLocInfo() == CCValAssign::SExt)
1895 DAG.getValueType(VA.getValVT()));
1896 else if (VA.getLocInfo() == CCValAssign::ZExt)
1898 DAG.getValueType(VA.getValVT()));
1899
1900 if (VA.isExtInLoc())
1901 Value = DAG.getNode(ISD::TRUNCATE, DL, VA.getValVT(), Value);
1902 else if (VA.getLocInfo() == CCValAssign::BCvt) {
1903 // If this is a short vector argument loaded from the stack,
1904 // extend from i64 to full vector size and then bitcast.
1905 assert(VA.getLocVT() == MVT::i64);
1906 assert(VA.getValVT().isVector());
1907 Value = DAG.getBuildVector(MVT::v2i64, DL, {Value, DAG.getUNDEF(MVT::i64)});
1908 Value = DAG.getNode(ISD::BITCAST, DL, VA.getValVT(), Value);
1909 } else
1910 assert(VA.getLocInfo() == CCValAssign::Full && "Unsupported getLocInfo");
1911 return Value;
1912}
1913
1914// Value is a value of type VA.getValVT() that we need to copy into
1915// the location described by VA. Return a copy of Value converted to
1916// VA.getValVT(). The caller is responsible for handling indirect values.
1918 CCValAssign &VA, SDValue Value) {
1919 switch (VA.getLocInfo()) {
1920 case CCValAssign::SExt:
1921 return DAG.getNode(ISD::SIGN_EXTEND, DL, VA.getLocVT(), Value);
1922 case CCValAssign::ZExt:
1923 return DAG.getNode(ISD::ZERO_EXTEND, DL, VA.getLocVT(), Value);
1924 case CCValAssign::AExt:
1925 return DAG.getNode(ISD::ANY_EXTEND, DL, VA.getLocVT(), Value);
1926 case CCValAssign::BCvt: {
1927 assert(VA.getLocVT() == MVT::i64 || VA.getLocVT() == MVT::i128);
1928 assert(VA.getValVT().isVector() || VA.getValVT() == MVT::f32 ||
1929 VA.getValVT() == MVT::f64 || VA.getValVT() == MVT::f128);
1930 // For an f32 vararg we need to first promote it to an f64 and then
1931 // bitcast it to an i64.
1932 if (VA.getValVT() == MVT::f32 && VA.getLocVT() == MVT::i64)
1933 Value = DAG.getNode(ISD::FP_EXTEND, DL, MVT::f64, Value);
1934 MVT BitCastToType = VA.getValVT().isVector() && VA.getLocVT() == MVT::i64
1935 ? MVT::v2i64
1936 : VA.getLocVT();
1937 Value = DAG.getNode(ISD::BITCAST, DL, BitCastToType, Value);
1938 // For ELF, this is a short vector argument to be stored to the stack,
1939 // bitcast to v2i64 and then extract first element.
1940 if (BitCastToType == MVT::v2i64)
1941 return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, VA.getLocVT(), Value,
1942 DAG.getConstant(0, DL, MVT::i32));
1943 return Value;
1944 }
1945 case CCValAssign::Full:
1946 return Value;
1947 default:
1948 llvm_unreachable("Unhandled getLocInfo()");
1949 }
1950}
1951
1953 SDLoc DL(In);
1954 SDValue Lo, Hi;
1955 if (DAG.getTargetLoweringInfo().isTypeLegal(MVT::i128)) {
1956 Lo = DAG.getNode(ISD::TRUNCATE, DL, MVT::i64, In);
1957 Hi = DAG.getNode(ISD::TRUNCATE, DL, MVT::i64,
1958 DAG.getNode(ISD::SRL, DL, MVT::i128, In,
1959 DAG.getConstant(64, DL, MVT::i32)));
1960 } else {
1961 std::tie(Lo, Hi) = DAG.SplitScalar(In, DL, MVT::i64, MVT::i64);
1962 }
1963
1964 // FIXME: If v2i64 were a legal type, we could use it instead of
1965 // Untyped here. This might enable improved folding.
1966 SDNode *Pair = DAG.getMachineNode(SystemZ::PAIR128, DL,
1967 MVT::Untyped, Hi, Lo);
1968 return SDValue(Pair, 0);
1969}
1970
1972 SDLoc DL(In);
1973 SDValue Hi = DAG.getTargetExtractSubreg(SystemZ::subreg_h64,
1974 DL, MVT::i64, In);
1975 SDValue Lo = DAG.getTargetExtractSubreg(SystemZ::subreg_l64,
1976 DL, MVT::i64, In);
1977
1978 if (DAG.getTargetLoweringInfo().isTypeLegal(MVT::i128)) {
1979 Lo = DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i128, Lo);
1980 Hi = DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i128, Hi);
1981 Hi = DAG.getNode(ISD::SHL, DL, MVT::i128, Hi,
1982 DAG.getConstant(64, DL, MVT::i32));
1983 return DAG.getNode(ISD::OR, DL, MVT::i128, Lo, Hi);
1984 } else {
1985 return DAG.getNode(ISD::BUILD_PAIR, DL, MVT::i128, Lo, Hi);
1986 }
1987}
1988
1990 SelectionDAG &DAG, const SDLoc &DL, SDValue Val, SDValue *Parts,
1991 unsigned NumParts, MVT PartVT, std::optional<CallingConv::ID> CC) const {
1992 EVT ValueVT = Val.getValueType();
1993 if (ValueVT.getSizeInBits() == 128 && NumParts == 1 && PartVT == MVT::Untyped) {
1994 // Inline assembly operand.
1995 Parts[0] = lowerI128ToGR128(DAG, DAG.getBitcast(MVT::i128, Val));
1996 return true;
1997 }
1998
1999 return false;
2000}
2001
2003 SelectionDAG &DAG, const SDLoc &DL, const SDValue *Parts, unsigned NumParts,
2004 MVT PartVT, EVT ValueVT, std::optional<CallingConv::ID> CC) const {
2005 if (ValueVT.getSizeInBits() == 128 && NumParts == 1 && PartVT == MVT::Untyped) {
2006 // Inline assembly operand.
2007 SDValue Res = lowerGR128ToI128(DAG, Parts[0]);
2008 return DAG.getBitcast(ValueVT, Res);
2009 }
2010
2011 return SDValue();
2012}
2013
2014// The first part of a split stack argument is at index I in Args (and
2015// ArgLocs). Return the type of a part and the number of them by reference.
2016template <class ArgTy>
2018 SmallVector<CCValAssign, 16> &ArgLocs, unsigned I,
2019 MVT &PartVT, unsigned &NumParts) {
2020 if (!Args[I].Flags.isSplit())
2021 return false;
2022 assert(I < ArgLocs.size() && ArgLocs.size() == Args.size() &&
2023 "ArgLocs havoc.");
2024 PartVT = ArgLocs[I].getValVT();
2025 NumParts = 1;
2026 for (unsigned PartIdx = I + 1;; ++PartIdx) {
2027 assert(PartIdx != ArgLocs.size() && "SplitEnd not found.");
2028 assert(ArgLocs[PartIdx].getValVT() == PartVT && "Unsupported split.");
2029 ++NumParts;
2030 if (Args[PartIdx].Flags.isSplitEnd())
2031 break;
2032 }
2033 return true;
2034}
2035
2037 SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
2038 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
2039 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
2041 MachineFrameInfo &MFI = MF.getFrameInfo();
2042 MachineRegisterInfo &MRI = MF.getRegInfo();
2043 SystemZMachineFunctionInfo *FuncInfo =
2045 auto *TFL = Subtarget.getFrameLowering<SystemZELFFrameLowering>();
2046 EVT PtrVT = getPointerTy(DAG.getDataLayout());
2047
2048 // Assign locations to all of the incoming arguments.
2050 CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext());
2051 CCInfo.AnalyzeFormalArguments(Ins, CC_SystemZ);
2052 FuncInfo->setSizeOfFnParams(CCInfo.getStackSize());
2053
2054 unsigned NumFixedGPRs = 0;
2055 unsigned NumFixedFPRs = 0;
2056 for (unsigned I = 0, E = ArgLocs.size(); I != E; ++I) {
2057 SDValue ArgValue;
2058 CCValAssign &VA = ArgLocs[I];
2059 EVT LocVT = VA.getLocVT();
2060 if (VA.isRegLoc()) {
2061 // Arguments passed in registers
2062 const TargetRegisterClass *RC;
2063 switch (LocVT.getSimpleVT().SimpleTy) {
2064 default:
2065 // Integers smaller than i64 should be promoted to i64.
2066 llvm_unreachable("Unexpected argument type");
2067 case MVT::i32:
2068 NumFixedGPRs += 1;
2069 RC = &SystemZ::GR32BitRegClass;
2070 break;
2071 case MVT::i64:
2072 NumFixedGPRs += 1;
2073 RC = &SystemZ::GR64BitRegClass;
2074 break;
2075 case MVT::f16:
2076 NumFixedFPRs += 1;
2077 RC = &SystemZ::FP16BitRegClass;
2078 break;
2079 case MVT::f32:
2080 NumFixedFPRs += 1;
2081 RC = &SystemZ::FP32BitRegClass;
2082 break;
2083 case MVT::f64:
2084 NumFixedFPRs += 1;
2085 RC = &SystemZ::FP64BitRegClass;
2086 break;
2087 case MVT::f128:
2088 NumFixedFPRs += 2;
2089 RC = &SystemZ::FP128BitRegClass;
2090 break;
2091 case MVT::v16i8:
2092 case MVT::v8i16:
2093 case MVT::v4i32:
2094 case MVT::v2i64:
2095 case MVT::v8f16:
2096 case MVT::v4f32:
2097 case MVT::v2f64:
2098 RC = &SystemZ::VR128BitRegClass;
2099 break;
2100 }
2101
2102 Register VReg = MRI.createVirtualRegister(RC);
2103 MRI.addLiveIn(VA.getLocReg(), VReg);
2104 ArgValue = DAG.getCopyFromReg(Chain, DL, VReg, LocVT);
2105 } else {
2106 assert(VA.isMemLoc() && "Argument not register or memory");
2107
2108 // Create the frame index object for this incoming parameter.
2109 // FIXME: Pre-include call frame size in the offset, should not
2110 // need to manually add it here.
2111 int64_t ArgSPOffset = VA.getLocMemOffset();
2112 if (Subtarget.isTargetXPLINK64()) {
2113 auto &XPRegs =
2114 Subtarget.getSpecialRegisters<SystemZXPLINK64Registers>();
2115 ArgSPOffset += XPRegs.getCallFrameSize();
2116 }
2117 int FI =
2118 MFI.CreateFixedObject(LocVT.getSizeInBits() / 8, ArgSPOffset, true);
2119
2120 // Create the SelectionDAG nodes corresponding to a load
2121 // from this parameter. Unpromoted ints and floats are
2122 // passed as right-justified 8-byte values.
2123 SDValue FIN = DAG.getFrameIndex(FI, PtrVT);
2124 if (VA.getLocVT() == MVT::i32 || VA.getLocVT() == MVT::f32 ||
2125 VA.getLocVT() == MVT::f16) {
2126 unsigned SlotOffs = VA.getLocVT() == MVT::f16 ? 6 : 4;
2127 FIN = DAG.getNode(ISD::ADD, DL, PtrVT, FIN,
2128 DAG.getIntPtrConstant(SlotOffs, DL));
2129 }
2130 ArgValue = DAG.getLoad(LocVT, DL, Chain, FIN,
2132 }
2133
2134 // Convert the value of the argument register into the value that's
2135 // being passed.
2136 if (VA.getLocInfo() == CCValAssign::Indirect) {
2137 InVals.push_back(DAG.getLoad(VA.getValVT(), DL, Chain, ArgValue,
2139 // If the original argument was split (e.g. i128), we need
2140 // to load all parts of it here (using the same address).
2141 MVT PartVT;
2142 unsigned NumParts;
2143 if (analyzeArgSplit(Ins, ArgLocs, I, PartVT, NumParts)) {
2144 for (unsigned PartIdx = 1; PartIdx < NumParts; ++PartIdx) {
2145 ++I;
2146 CCValAssign &PartVA = ArgLocs[I];
2147 unsigned PartOffset = Ins[I].PartOffset;
2148 SDValue Address = DAG.getNode(ISD::ADD, DL, PtrVT, ArgValue,
2149 DAG.getIntPtrConstant(PartOffset, DL));
2150 InVals.push_back(DAG.getLoad(PartVA.getValVT(), DL, Chain, Address,
2152 assert(PartOffset && "Offset should be non-zero.");
2153 }
2154 }
2155 } else
2156 InVals.push_back(convertLocVTToValVT(DAG, DL, VA, Chain, ArgValue));
2157 }
2158
2159 if (IsVarArg && Subtarget.isTargetXPLINK64()) {
2160 // Save the number of non-varargs registers for later use by va_start, etc.
2161 FuncInfo->setVarArgsFirstGPR(NumFixedGPRs);
2162 FuncInfo->setVarArgsFirstFPR(NumFixedFPRs);
2163
2164 auto *Regs = static_cast<SystemZXPLINK64Registers *>(
2165 Subtarget.getSpecialRegisters());
2166
2167 // Likewise the address (in the form of a frame index) of where the
2168 // first stack vararg would be. The 1-byte size here is arbitrary.
2169 // FIXME: Pre-include call frame size in the offset, should not
2170 // need to manually add it here.
2171 int64_t VarArgOffset = CCInfo.getStackSize() + Regs->getCallFrameSize();
2172 int FI = MFI.CreateFixedObject(1, VarArgOffset, true);
2173 FuncInfo->setVarArgsFrameIndex(FI);
2174 }
2175
2176 if (IsVarArg && Subtarget.isTargetELF()) {
2177 // Save the number of non-varargs registers for later use by va_start, etc.
2178 FuncInfo->setVarArgsFirstGPR(NumFixedGPRs);
2179 FuncInfo->setVarArgsFirstFPR(NumFixedFPRs);
2180
2181 // Likewise the address (in the form of a frame index) of where the
2182 // first stack vararg would be. The 1-byte size here is arbitrary.
2183 int64_t VarArgsOffset = CCInfo.getStackSize();
2184 FuncInfo->setVarArgsFrameIndex(
2185 MFI.CreateFixedObject(1, VarArgsOffset, true));
2186
2187 // ...and a similar frame index for the caller-allocated save area
2188 // that will be used to store the incoming registers.
2189 int64_t RegSaveOffset =
2190 -SystemZMC::ELFCallFrameSize + TFL->getRegSpillOffset(MF, SystemZ::R2D) - 16;
2191 unsigned RegSaveIndex = MFI.CreateFixedObject(1, RegSaveOffset, true);
2192 FuncInfo->setRegSaveFrameIndex(RegSaveIndex);
2193
2194 // Store the FPR varargs in the reserved frame slots. (We store the
2195 // GPRs as part of the prologue.)
2196 if (NumFixedFPRs < SystemZ::ELFNumArgFPRs && !useSoftFloat()) {
2198 for (unsigned I = NumFixedFPRs; I < SystemZ::ELFNumArgFPRs; ++I) {
2199 unsigned Offset = TFL->getRegSpillOffset(MF, SystemZ::ELFArgFPRs[I]);
2200 int FI =
2202 SDValue FIN = DAG.getFrameIndex(FI, getPointerTy(DAG.getDataLayout()));
2204 &SystemZ::FP64BitRegClass);
2205 SDValue ArgValue = DAG.getCopyFromReg(Chain, DL, VReg, MVT::f64);
2206 MemOps[I] = DAG.getStore(ArgValue.getValue(1), DL, ArgValue, FIN,
2208 }
2209 // Join the stores, which are independent of one another.
2210 Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other,
2211 ArrayRef(&MemOps[NumFixedFPRs],
2212 SystemZ::ELFNumArgFPRs - NumFixedFPRs));
2213 }
2214 }
2215
2216 if (Subtarget.isTargetXPLINK64()) {
2217 // Create virual register for handling incoming "ADA" special register (R5)
2218 const TargetRegisterClass *RC = &SystemZ::ADDR64BitRegClass;
2219 Register ADAvReg = MRI.createVirtualRegister(RC);
2220 auto *Regs = static_cast<SystemZXPLINK64Registers *>(
2221 Subtarget.getSpecialRegisters());
2222 MRI.addLiveIn(Regs->getADARegister(), ADAvReg);
2223 FuncInfo->setADAVirtualRegister(ADAvReg);
2224 }
2225 return Chain;
2226}
2227
2228static bool canUseSiblingCall(const CCState &ArgCCInfo,
2231 // Punt if there are any indirect or stack arguments, or if the call
2232 // needs the callee-saved argument register R6, or if the call uses
2233 // the callee-saved register arguments SwiftSelf and SwiftError.
2234 for (unsigned I = 0, E = ArgLocs.size(); I != E; ++I) {
2235 CCValAssign &VA = ArgLocs[I];
2237 return false;
2238 if (!VA.isRegLoc())
2239 return false;
2240 Register Reg = VA.getLocReg();
2241 if (Reg == SystemZ::R6H || Reg == SystemZ::R6L || Reg == SystemZ::R6D)
2242 return false;
2243 if (Outs[I].Flags.isSwiftSelf() || Outs[I].Flags.isSwiftError())
2244 return false;
2245 }
2246 return true;
2247}
2248
2250 unsigned Offset, bool LoadAdr = false) {
2253 Register ADAvReg = MFI->getADAVirtualRegister();
2255
2256 SDValue Reg = DAG.getRegister(ADAvReg, PtrVT);
2257 SDValue Ofs = DAG.getTargetConstant(Offset, DL, PtrVT);
2258
2259 SDValue Result = DAG.getNode(SystemZISD::ADA_ENTRY, DL, PtrVT, Val, Reg, Ofs);
2260 if (!LoadAdr)
2261 Result = DAG.getLoad(
2262 PtrVT, DL, DAG.getEntryNode(), Result, MachinePointerInfo(), Align(8),
2264
2265 return Result;
2266}
2267
2268// ADA access using Global value
2269// Note: for functions, address of descriptor is returned
2271 EVT PtrVT) {
2272 unsigned ADAtype;
2273 bool LoadAddr = false;
2274 const GlobalAlias *GA = dyn_cast<GlobalAlias>(GV);
2275 bool IsFunction =
2276 (isa<Function>(GV)) || (GA && isa<Function>(GA->getAliaseeObject()));
2277 bool IsInternal = (GV->hasInternalLinkage() || GV->hasPrivateLinkage());
2278
2279 if (IsFunction) {
2280 if (IsInternal) {
2282 LoadAddr = true;
2283 } else
2285 } else {
2287 }
2288 SDValue Val = DAG.getTargetGlobalAddress(GV, DL, PtrVT, 0, ADAtype);
2289
2290 return getADAEntry(DAG, Val, DL, 0, LoadAddr);
2291}
2292
2293static bool getzOSCalleeAndADA(SelectionDAG &DAG, SDValue &Callee, SDValue &ADA,
2294 SDLoc &DL, SDValue &Chain) {
2295 unsigned ADADelta = 0; // ADA offset in desc.
2296 unsigned EPADelta = 8; // EPA offset in desc.
2299
2300 // XPLink calling convention.
2301 if (auto *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
2302 bool IsInternal = (G->getGlobal()->hasInternalLinkage() ||
2303 G->getGlobal()->hasPrivateLinkage());
2304 if (IsInternal) {
2307 Register ADAvReg = MFI->getADAVirtualRegister();
2308 ADA = DAG.getCopyFromReg(Chain, DL, ADAvReg, PtrVT);
2309 Callee = DAG.getTargetGlobalAddress(G->getGlobal(), DL, PtrVT);
2310 Callee = DAG.getNode(SystemZISD::PCREL_WRAPPER, DL, PtrVT, Callee);
2311 return true;
2312 } else {
2314 G->getGlobal(), DL, PtrVT, 0, SystemZII::MO_ADA_DIRECT_FUNC_DESC);
2315 ADA = getADAEntry(DAG, GA, DL, ADADelta);
2316 Callee = getADAEntry(DAG, GA, DL, EPADelta);
2317 }
2318 } else if (auto *E = dyn_cast<ExternalSymbolSDNode>(Callee)) {
2320 E->getSymbol(), PtrVT, SystemZII::MO_ADA_DIRECT_FUNC_DESC);
2321 ADA = getADAEntry(DAG, ES, DL, ADADelta);
2322 Callee = getADAEntry(DAG, ES, DL, EPADelta);
2323 } else {
2324 // Function pointer case
2325 ADA = DAG.getNode(ISD::ADD, DL, PtrVT, Callee,
2326 DAG.getConstant(ADADelta, DL, PtrVT));
2327 ADA = DAG.getLoad(PtrVT, DL, DAG.getEntryNode(), ADA,
2329 Callee = DAG.getNode(ISD::ADD, DL, PtrVT, Callee,
2330 DAG.getConstant(EPADelta, DL, PtrVT));
2331 Callee = DAG.getLoad(PtrVT, DL, DAG.getEntryNode(), Callee,
2333 }
2334 return false;
2335}
2336
2337SDValue
2339 SmallVectorImpl<SDValue> &InVals) const {
2340 SelectionDAG &DAG = CLI.DAG;
2341 SDLoc &DL = CLI.DL;
2343 SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
2345 SDValue Chain = CLI.Chain;
2346 SDValue Callee = CLI.Callee;
2347 bool &IsTailCall = CLI.IsTailCall;
2348 CallingConv::ID CallConv = CLI.CallConv;
2349 bool IsVarArg = CLI.IsVarArg;
2351 EVT PtrVT = getPointerTy(MF.getDataLayout());
2352 LLVMContext &Ctx = *DAG.getContext();
2353 SystemZCallingConventionRegisters *Regs = Subtarget.getSpecialRegisters();
2354
2355 // FIXME: z/OS support to be added in later.
2356 if (Subtarget.isTargetXPLINK64())
2357 IsTailCall = false;
2358
2359 // Integer args <=32 bits should have an extension attribute.
2360 verifyNarrowIntegerArgs_Call(Outs, &MF.getFunction(), Callee);
2361
2362 // Analyze the operands of the call, assigning locations to each operand.
2364 CCState ArgCCInfo(CallConv, IsVarArg, MF, ArgLocs, Ctx);
2365 ArgCCInfo.AnalyzeCallOperands(Outs, CC_SystemZ);
2366
2367 // We don't support GuaranteedTailCallOpt, only automatically-detected
2368 // sibling calls.
2369 if (IsTailCall && !canUseSiblingCall(ArgCCInfo, ArgLocs, Outs))
2370 IsTailCall = false;
2371
2372 // Get a count of how many bytes are to be pushed on the stack.
2373 unsigned NumBytes = ArgCCInfo.getStackSize();
2374
2375 // Mark the start of the call.
2376 if (!IsTailCall)
2377 Chain = DAG.getCALLSEQ_START(Chain, NumBytes, 0, DL);
2378
2379 // Copy argument values to their designated locations.
2381 SmallVector<SDValue, 8> MemOpChains;
2382 SDValue StackPtr;
2383 for (unsigned I = 0, E = ArgLocs.size(); I != E; ++I) {
2384 CCValAssign &VA = ArgLocs[I];
2385 SDValue ArgValue = OutVals[I];
2386
2387 if (VA.getLocInfo() == CCValAssign::Indirect) {
2388 // Store the argument in a stack slot and pass its address.
2389 EVT SlotVT;
2390 MVT PartVT;
2391 unsigned NumParts = 1;
2392 if (analyzeArgSplit(Outs, ArgLocs, I, PartVT, NumParts))
2393 SlotVT = EVT::getIntegerVT(Ctx, PartVT.getSizeInBits() * NumParts);
2394 else
2395 SlotVT = Outs[I].VT;
2396 SDValue SpillSlot = DAG.CreateStackTemporary(SlotVT);
2397 int FI = cast<FrameIndexSDNode>(SpillSlot)->getIndex();
2398
2399 MachinePointerInfo StackPtrInfo =
2401 MemOpChains.push_back(
2402 DAG.getStore(Chain, DL, ArgValue, SpillSlot, StackPtrInfo));
2403 // If the original argument was split (e.g. i128), we need
2404 // to store all parts of it here (and pass just one address).
2405 assert(Outs[I].PartOffset == 0);
2406 for (unsigned PartIdx = 1; PartIdx < NumParts; ++PartIdx) {
2407 ++I;
2408 SDValue PartValue = OutVals[I];
2409 unsigned PartOffset = Outs[I].PartOffset;
2410 SDValue Address = DAG.getNode(ISD::ADD, DL, PtrVT, SpillSlot,
2411 DAG.getIntPtrConstant(PartOffset, DL));
2412 MemOpChains.push_back(
2413 DAG.getStore(Chain, DL, PartValue, Address,
2414 StackPtrInfo.getWithOffset(PartOffset)));
2415 assert(PartOffset && "Offset should be non-zero.");
2416 assert((PartOffset + PartValue.getValueType().getStoreSize() <=
2417 SlotVT.getStoreSize()) && "Not enough space for argument part!");
2418 }
2419 ArgValue = SpillSlot;
2420 } else
2421 ArgValue = convertValVTToLocVT(DAG, DL, VA, ArgValue);
2422
2423 if (VA.isRegLoc()) {
2424 // In XPLINK64, for the 128-bit vararg case, ArgValue is bitcasted to a
2425 // MVT::i128 type. We decompose the 128-bit type to a pair of its high
2426 // and low values.
2427 if (VA.getLocVT() == MVT::i128)
2428 ArgValue = lowerI128ToGR128(DAG, ArgValue);
2429 // Queue up the argument copies and emit them at the end.
2430 RegsToPass.push_back(std::make_pair(VA.getLocReg(), ArgValue));
2431 } else {
2432 assert(VA.isMemLoc() && "Argument not register or memory");
2433
2434 // Work out the address of the stack slot. Unpromoted ints and
2435 // floats are passed as right-justified 8-byte values.
2436 if (!StackPtr.getNode())
2437 StackPtr = DAG.getCopyFromReg(Chain, DL,
2438 Regs->getStackPointerRegister(), PtrVT);
2439 unsigned Offset = Regs->getStackPointerBias() + Regs->getCallFrameSize() +
2440 VA.getLocMemOffset();
2441 if (VA.getLocVT() == MVT::i32 || VA.getLocVT() == MVT::f32)
2442 Offset += 4;
2443 else if (VA.getLocVT() == MVT::f16)
2444 Offset += 6;
2445 SDValue Address = DAG.getNode(ISD::ADD, DL, PtrVT, StackPtr,
2447
2448 // Emit the store.
2449 MemOpChains.push_back(
2450 DAG.getStore(Chain, DL, ArgValue, Address, MachinePointerInfo()));
2451
2452 // Although long doubles or vectors are passed through the stack when
2453 // they are vararg (non-fixed arguments), if a long double or vector
2454 // occupies the third and fourth slot of the argument list GPR3 should
2455 // still shadow the third slot of the argument list.
2456 if (Subtarget.isTargetXPLINK64() && VA.needsCustom()) {
2457 SDValue ShadowArgValue =
2458 DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i64, ArgValue,
2459 DAG.getIntPtrConstant(1, DL));
2460 RegsToPass.push_back(std::make_pair(SystemZ::R3D, ShadowArgValue));
2461 }
2462 }
2463 }
2464
2465 // Join the stores, which are independent of one another.
2466 if (!MemOpChains.empty())
2467 Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, MemOpChains);
2468
2469 // Accept direct calls by converting symbolic call addresses to the
2470 // associated Target* opcodes. Force %r1 to be used for indirect
2471 // tail calls.
2472 SDValue Glue;
2473
2474 if (Subtarget.isTargetXPLINK64()) {
2475 SDValue ADA;
2476 bool IsBRASL = getzOSCalleeAndADA(DAG, Callee, ADA, DL, Chain);
2477 if (!IsBRASL) {
2478 unsigned CalleeReg = static_cast<SystemZXPLINK64Registers *>(Regs)
2479 ->getAddressOfCalleeRegister();
2480 Chain = DAG.getCopyToReg(Chain, DL, CalleeReg, Callee, Glue);
2481 Glue = Chain.getValue(1);
2482 Callee = DAG.getRegister(CalleeReg, Callee.getValueType());
2483 }
2484 RegsToPass.push_back(std::make_pair(
2485 static_cast<SystemZXPLINK64Registers *>(Regs)->getADARegister(), ADA));
2486 } else {
2487 if (auto *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
2488 Callee = DAG.getTargetGlobalAddress(G->getGlobal(), DL, PtrVT);
2489 Callee = DAG.getNode(SystemZISD::PCREL_WRAPPER, DL, PtrVT, Callee);
2490 } else if (auto *E = dyn_cast<ExternalSymbolSDNode>(Callee)) {
2491 Callee = DAG.getTargetExternalSymbol(E->getSymbol(), PtrVT);
2492 Callee = DAG.getNode(SystemZISD::PCREL_WRAPPER, DL, PtrVT, Callee);
2493 } else if (IsTailCall) {
2494 Chain = DAG.getCopyToReg(Chain, DL, SystemZ::R1D, Callee, Glue);
2495 Glue = Chain.getValue(1);
2496 Callee = DAG.getRegister(SystemZ::R1D, Callee.getValueType());
2497 }
2498 }
2499
2500 // Build a sequence of copy-to-reg nodes, chained and glued together.
2501 for (const auto &[Reg, N] : RegsToPass) {
2502 Chain = DAG.getCopyToReg(Chain, DL, Reg, N, Glue);
2503 Glue = Chain.getValue(1);
2504 }
2505
2506 // The first call operand is the chain and the second is the target address.
2508 Ops.push_back(Chain);
2509 Ops.push_back(Callee);
2510
2511 // Add argument registers to the end of the list so that they are
2512 // known live into the call.
2513 for (const auto &[Reg, N] : RegsToPass)
2514 Ops.push_back(DAG.getRegister(Reg, N.getValueType()));
2515
2516 // Add a register mask operand representing the call-preserved registers.
2517 const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();
2518 const uint32_t *Mask = TRI->getCallPreservedMask(MF, CallConv);
2519 assert(Mask && "Missing call preserved mask for calling convention");
2520 Ops.push_back(DAG.getRegisterMask(Mask));
2521
2522 // Glue the call to the argument copies, if any.
2523 if (Glue.getNode())
2524 Ops.push_back(Glue);
2525
2526 // Emit the call.
2527 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
2528 if (IsTailCall) {
2529 SDValue Ret = DAG.getNode(SystemZISD::SIBCALL, DL, NodeTys, Ops);
2530 DAG.addNoMergeSiteInfo(Ret.getNode(), CLI.NoMerge);
2531 return Ret;
2532 }
2533 Chain = DAG.getNode(SystemZISD::CALL, DL, NodeTys, Ops);
2534 DAG.addNoMergeSiteInfo(Chain.getNode(), CLI.NoMerge);
2535 Glue = Chain.getValue(1);
2536
2537 // Mark the end of the call, which is glued to the call itself.
2538 Chain = DAG.getCALLSEQ_END(Chain, NumBytes, 0, Glue, DL);
2539 Glue = Chain.getValue(1);
2540
2541 // Assign locations to each value returned by this call.
2543 CCState RetCCInfo(CallConv, IsVarArg, MF, RetLocs, Ctx);
2544 RetCCInfo.AnalyzeCallResult(Ins, RetCC_SystemZ);
2545
2546 // Copy all of the result registers out of their specified physreg.
2547 for (CCValAssign &VA : RetLocs) {
2548 // Copy the value out, gluing the copy to the end of the call sequence.
2549 SDValue RetValue = DAG.getCopyFromReg(Chain, DL, VA.getLocReg(),
2550 VA.getLocVT(), Glue);
2551 Chain = RetValue.getValue(1);
2552 Glue = RetValue.getValue(2);
2553
2554 // Convert the value of the return register into the value that's
2555 // being returned.
2556 InVals.push_back(convertLocVTToValVT(DAG, DL, VA, Chain, RetValue));
2557 }
2558
2559 return Chain;
2560}
2561
2562// Generate a call taking the given operands as arguments and returning a
2563// result of type RetVT.
2565 SDValue Chain, SelectionDAG &DAG, const char *CalleeName, EVT RetVT,
2566 ArrayRef<SDValue> Ops, CallingConv::ID CallConv, bool IsSigned, SDLoc DL,
2567 bool DoesNotReturn, bool IsReturnValueUsed) const {
2569 Args.reserve(Ops.size());
2570
2571 for (SDValue Op : Ops) {
2573 Op, Op.getValueType().getTypeForEVT(*DAG.getContext()));
2574 Entry.IsSExt = shouldSignExtendTypeInLibCall(Entry.Ty, IsSigned);
2575 Entry.IsZExt = !Entry.IsSExt;
2576 Args.push_back(Entry);
2577 }
2578
2579 SDValue Callee =
2580 DAG.getExternalSymbol(CalleeName, getPointerTy(DAG.getDataLayout()));
2581
2582 Type *RetTy = RetVT.getTypeForEVT(*DAG.getContext());
2584 bool SignExtend = shouldSignExtendTypeInLibCall(RetTy, IsSigned);
2585 CLI.setDebugLoc(DL)
2586 .setChain(Chain)
2587 .setCallee(CallConv, RetTy, Callee, std::move(Args))
2588 .setNoReturn(DoesNotReturn)
2589 .setDiscardResult(!IsReturnValueUsed)
2590 .setSExtResult(SignExtend)
2591 .setZExtResult(!SignExtend);
2592 return LowerCallTo(CLI);
2593}
2594
2596 CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg,
2597 const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context,
2598 const Type *RetTy) const {
2599 // Special case that we cannot easily detect in RetCC_SystemZ since
2600 // i128 may not be a legal type.
2601 for (auto &Out : Outs)
2602 if (Out.ArgVT.isScalarInteger() && Out.ArgVT.getSizeInBits() > 64)
2603 return false;
2604
2606 CCState RetCCInfo(CallConv, IsVarArg, MF, RetLocs, Context);
2607 return RetCCInfo.CheckReturn(Outs, RetCC_SystemZ);
2608}
2609
2610SDValue
2612 bool IsVarArg,
2614 const SmallVectorImpl<SDValue> &OutVals,
2615 const SDLoc &DL, SelectionDAG &DAG) const {
2617
2618 // Integer args <=32 bits should have an extension attribute.
2619 verifyNarrowIntegerArgs_Ret(Outs, &MF.getFunction());
2620
2621 // Assign locations to each returned value.
2623 CCState RetCCInfo(CallConv, IsVarArg, MF, RetLocs, *DAG.getContext());
2624 RetCCInfo.AnalyzeReturn(Outs, RetCC_SystemZ);
2625
2626 // Quick exit for void returns
2627 if (RetLocs.empty())
2628 return DAG.getNode(SystemZISD::RET_GLUE, DL, MVT::Other, Chain);
2629
2630 if (CallConv == CallingConv::GHC)
2631 report_fatal_error("GHC functions return void only");
2632
2633 // Copy the result values into the output registers.
2634 SDValue Glue;
2636 RetOps.push_back(Chain);
2637 for (unsigned I = 0, E = RetLocs.size(); I != E; ++I) {
2638 CCValAssign &VA = RetLocs[I];
2639 SDValue RetValue = OutVals[I];
2640
2641 // Make the return register live on exit.
2642 assert(VA.isRegLoc() && "Can only return in registers!");
2643
2644 // Promote the value as required.
2645 RetValue = convertValVTToLocVT(DAG, DL, VA, RetValue);
2646
2647 // Chain and glue the copies together.
2648 Register Reg = VA.getLocReg();
2649 Chain = DAG.getCopyToReg(Chain, DL, Reg, RetValue, Glue);
2650 Glue = Chain.getValue(1);
2651 RetOps.push_back(DAG.getRegister(Reg, VA.getLocVT()));
2652 }
2653
2654 // Update chain and glue.
2655 RetOps[0] = Chain;
2656 if (Glue.getNode())
2657 RetOps.push_back(Glue);
2658
2659 return DAG.getNode(SystemZISD::RET_GLUE, DL, MVT::Other, RetOps);
2660}
2661
2662// Return true if Op is an intrinsic node with chain that returns the CC value
2663// as its only (other) argument. Provide the associated SystemZISD opcode and
2664// the mask of valid CC values if so.
2665static bool isIntrinsicWithCCAndChain(SDValue Op, unsigned &Opcode,
2666 unsigned &CCValid) {
2667 unsigned Id = Op.getConstantOperandVal(1);
2668 switch (Id) {
2669 case Intrinsic::s390_tbegin:
2670 Opcode = SystemZISD::TBEGIN;
2671 CCValid = SystemZ::CCMASK_TBEGIN;
2672 return true;
2673
2674 case Intrinsic::s390_tbegin_nofloat:
2675 Opcode = SystemZISD::TBEGIN_NOFLOAT;
2676 CCValid = SystemZ::CCMASK_TBEGIN;
2677 return true;
2678
2679 case Intrinsic::s390_tend:
2680 Opcode = SystemZISD::TEND;
2681 CCValid = SystemZ::CCMASK_TEND;
2682 return true;
2683
2684 default:
2685 return false;
2686 }
2687}
2688
2689// Return true if Op is an intrinsic node without chain that returns the
2690// CC value as its final argument. Provide the associated SystemZISD
2691// opcode and the mask of valid CC values if so.
2692static bool isIntrinsicWithCC(SDValue Op, unsigned &Opcode, unsigned &CCValid) {
2693 unsigned Id = Op.getConstantOperandVal(0);
2694 switch (Id) {
2695 case Intrinsic::s390_vpkshs:
2696 case Intrinsic::s390_vpksfs:
2697 case Intrinsic::s390_vpksgs:
2698 Opcode = SystemZISD::PACKS_CC;
2699 CCValid = SystemZ::CCMASK_VCMP;
2700 return true;
2701
2702 case Intrinsic::s390_vpklshs:
2703 case Intrinsic::s390_vpklsfs:
2704 case Intrinsic::s390_vpklsgs:
2705 Opcode = SystemZISD::PACKLS_CC;
2706 CCValid = SystemZ::CCMASK_VCMP;
2707 return true;
2708
2709 case Intrinsic::s390_vceqbs:
2710 case Intrinsic::s390_vceqhs:
2711 case Intrinsic::s390_vceqfs:
2712 case Intrinsic::s390_vceqgs:
2713 case Intrinsic::s390_vceqqs:
2714 Opcode = SystemZISD::VICMPES;
2715 CCValid = SystemZ::CCMASK_VCMP;
2716 return true;
2717
2718 case Intrinsic::s390_vchbs:
2719 case Intrinsic::s390_vchhs:
2720 case Intrinsic::s390_vchfs:
2721 case Intrinsic::s390_vchgs:
2722 case Intrinsic::s390_vchqs:
2723 Opcode = SystemZISD::VICMPHS;
2724 CCValid = SystemZ::CCMASK_VCMP;
2725 return true;
2726
2727 case Intrinsic::s390_vchlbs:
2728 case Intrinsic::s390_vchlhs:
2729 case Intrinsic::s390_vchlfs:
2730 case Intrinsic::s390_vchlgs:
2731 case Intrinsic::s390_vchlqs:
2732 Opcode = SystemZISD::VICMPHLS;
2733 CCValid = SystemZ::CCMASK_VCMP;
2734 return true;
2735
2736 case Intrinsic::s390_vtm:
2737 Opcode = SystemZISD::VTM;
2738 CCValid = SystemZ::CCMASK_VCMP;
2739 return true;
2740
2741 case Intrinsic::s390_vfaebs:
2742 case Intrinsic::s390_vfaehs:
2743 case Intrinsic::s390_vfaefs:
2744 Opcode = SystemZISD::VFAE_CC;
2745 CCValid = SystemZ::CCMASK_ANY;
2746 return true;
2747
2748 case Intrinsic::s390_vfaezbs:
2749 case Intrinsic::s390_vfaezhs:
2750 case Intrinsic::s390_vfaezfs:
2751 Opcode = SystemZISD::VFAEZ_CC;
2752 CCValid = SystemZ::CCMASK_ANY;
2753 return true;
2754
2755 case Intrinsic::s390_vfeebs:
2756 case Intrinsic::s390_vfeehs:
2757 case Intrinsic::s390_vfeefs:
2758 Opcode = SystemZISD::VFEE_CC;
2759 CCValid = SystemZ::CCMASK_ANY;
2760 return true;
2761
2762 case Intrinsic::s390_vfeezbs:
2763 case Intrinsic::s390_vfeezhs:
2764 case Intrinsic::s390_vfeezfs:
2765 Opcode = SystemZISD::VFEEZ_CC;
2766 CCValid = SystemZ::CCMASK_ANY;
2767 return true;
2768
2769 case Intrinsic::s390_vfenebs:
2770 case Intrinsic::s390_vfenehs:
2771 case Intrinsic::s390_vfenefs:
2772 Opcode = SystemZISD::VFENE_CC;
2773 CCValid = SystemZ::CCMASK_ANY;
2774 return true;
2775
2776 case Intrinsic::s390_vfenezbs:
2777 case Intrinsic::s390_vfenezhs:
2778 case Intrinsic::s390_vfenezfs:
2779 Opcode = SystemZISD::VFENEZ_CC;
2780 CCValid = SystemZ::CCMASK_ANY;
2781 return true;
2782
2783 case Intrinsic::s390_vistrbs:
2784 case Intrinsic::s390_vistrhs:
2785 case Intrinsic::s390_vistrfs:
2786 Opcode = SystemZISD::VISTR_CC;
2788 return true;
2789
2790 case Intrinsic::s390_vstrcbs:
2791 case Intrinsic::s390_vstrchs:
2792 case Intrinsic::s390_vstrcfs:
2793 Opcode = SystemZISD::VSTRC_CC;
2794 CCValid = SystemZ::CCMASK_ANY;
2795 return true;
2796
2797 case Intrinsic::s390_vstrczbs:
2798 case Intrinsic::s390_vstrczhs:
2799 case Intrinsic::s390_vstrczfs:
2800 Opcode = SystemZISD::VSTRCZ_CC;
2801 CCValid = SystemZ::CCMASK_ANY;
2802 return true;
2803
2804 case Intrinsic::s390_vstrsb:
2805 case Intrinsic::s390_vstrsh:
2806 case Intrinsic::s390_vstrsf:
2807 Opcode = SystemZISD::VSTRS_CC;
2808 CCValid = SystemZ::CCMASK_ANY;
2809 return true;
2810
2811 case Intrinsic::s390_vstrszb:
2812 case Intrinsic::s390_vstrszh:
2813 case Intrinsic::s390_vstrszf:
2814 Opcode = SystemZISD::VSTRSZ_CC;
2815 CCValid = SystemZ::CCMASK_ANY;
2816 return true;
2817
2818 case Intrinsic::s390_vfcedbs:
2819 case Intrinsic::s390_vfcesbs:
2820 Opcode = SystemZISD::VFCMPES;
2821 CCValid = SystemZ::CCMASK_VCMP;
2822 return true;
2823
2824 case Intrinsic::s390_vfchdbs:
2825 case Intrinsic::s390_vfchsbs:
2826 Opcode = SystemZISD::VFCMPHS;
2827 CCValid = SystemZ::CCMASK_VCMP;
2828 return true;
2829
2830 case Intrinsic::s390_vfchedbs:
2831 case Intrinsic::s390_vfchesbs:
2832 Opcode = SystemZISD::VFCMPHES;
2833 CCValid = SystemZ::CCMASK_VCMP;
2834 return true;
2835
2836 case Intrinsic::s390_vftcidb:
2837 case Intrinsic::s390_vftcisb:
2838 Opcode = SystemZISD::VFTCI;
2839 CCValid = SystemZ::CCMASK_VCMP;
2840 return true;
2841
2842 case Intrinsic::s390_tdc:
2843 Opcode = SystemZISD::TDC;
2844 CCValid = SystemZ::CCMASK_TDC;
2845 return true;
2846
2847 default:
2848 return false;
2849 }
2850}
2851
2852// Emit an intrinsic with chain and an explicit CC register result.
2854 unsigned Opcode) {
2855 // Copy all operands except the intrinsic ID.
2856 unsigned NumOps = Op.getNumOperands();
2858 Ops.reserve(NumOps - 1);
2859 Ops.push_back(Op.getOperand(0));
2860 for (unsigned I = 2; I < NumOps; ++I)
2861 Ops.push_back(Op.getOperand(I));
2862
2863 assert(Op->getNumValues() == 2 && "Expected only CC result and chain");
2864 SDVTList RawVTs = DAG.getVTList(MVT::i32, MVT::Other);
2865 SDValue Intr = DAG.getNode(Opcode, SDLoc(Op), RawVTs, Ops);
2866 SDValue OldChain = SDValue(Op.getNode(), 1);
2867 SDValue NewChain = SDValue(Intr.getNode(), 1);
2868 DAG.ReplaceAllUsesOfValueWith(OldChain, NewChain);
2869 return Intr.getNode();
2870}
2871
2872// Emit an intrinsic with an explicit CC register result.
2874 unsigned Opcode) {
2875 // Copy all operands except the intrinsic ID.
2876 SDLoc DL(Op);
2877 unsigned NumOps = Op.getNumOperands();
2879 Ops.reserve(NumOps - 1);
2880 for (unsigned I = 1; I < NumOps; ++I) {
2881 SDValue CurrOper = Op.getOperand(I);
2882 if (CurrOper.getValueType() == MVT::f16) {
2883 assert((Op.getConstantOperandVal(0) == Intrinsic::s390_tdc && I == 1) &&
2884 "Unhandled intrinsic with f16 operand.");
2885 CurrOper = DAG.getFPExtendOrRound(CurrOper, DL, MVT::f32);
2886 }
2887 Ops.push_back(CurrOper);
2888 }
2889
2890 SDValue Intr = DAG.getNode(Opcode, DL, Op->getVTList(), Ops);
2891 return Intr.getNode();
2892}
2893
2894// CC is a comparison that will be implemented using an integer or
2895// floating-point comparison. Return the condition code mask for
2896// a branch on true. In the integer case, CCMASK_CMP_UO is set for
2897// unsigned comparisons and clear for signed ones. In the floating-point
2898// case, CCMASK_CMP_UO has its normal mask meaning (unordered).
2900#define CONV(X) \
2901 case ISD::SET##X: return SystemZ::CCMASK_CMP_##X; \
2902 case ISD::SETO##X: return SystemZ::CCMASK_CMP_##X; \
2903 case ISD::SETU##X: return SystemZ::CCMASK_CMP_UO | SystemZ::CCMASK_CMP_##X
2904
2905 switch (CC) {
2906 default:
2907 llvm_unreachable("Invalid integer condition!");
2908
2909 CONV(EQ);
2910 CONV(NE);
2911 CONV(GT);
2912 CONV(GE);
2913 CONV(LT);
2914 CONV(LE);
2915
2916 case ISD::SETO: return SystemZ::CCMASK_CMP_O;
2918 }
2919#undef CONV
2920}
2921
2922// If C can be converted to a comparison against zero, adjust the operands
2923// as necessary.
2924static void adjustZeroCmp(SelectionDAG &DAG, const SDLoc &DL, Comparison &C) {
2925 if (C.ICmpType == SystemZICMP::UnsignedOnly)
2926 return;
2927
2928 auto *ConstOp1 = dyn_cast<ConstantSDNode>(C.Op1.getNode());
2929 if (!ConstOp1 || ConstOp1->getValueSizeInBits(0) > 64)
2930 return;
2931
2932 int64_t Value = ConstOp1->getSExtValue();
2933 if ((Value == -1 && C.CCMask == SystemZ::CCMASK_CMP_GT) ||
2934 (Value == -1 && C.CCMask == SystemZ::CCMASK_CMP_LE) ||
2935 (Value == 1 && C.CCMask == SystemZ::CCMASK_CMP_LT) ||
2936 (Value == 1 && C.CCMask == SystemZ::CCMASK_CMP_GE)) {
2937 C.CCMask ^= SystemZ::CCMASK_CMP_EQ;
2938 C.Op1 = DAG.getConstant(0, DL, C.Op1.getValueType());
2939 }
2940}
2941
2942// If a comparison described by C is suitable for CLI(Y), CHHSI or CLHHSI,
2943// adjust the operands as necessary.
2944static void adjustSubwordCmp(SelectionDAG &DAG, const SDLoc &DL,
2945 Comparison &C) {
2946 // For us to make any changes, it must a comparison between a single-use
2947 // load and a constant.
2948 if (!C.Op0.hasOneUse() ||
2949 C.Op0.getOpcode() != ISD::LOAD ||
2950 C.Op1.getOpcode() != ISD::Constant)
2951 return;
2952
2953 // We must have an 8- or 16-bit load.
2954 auto *Load = cast<LoadSDNode>(C.Op0);
2955 unsigned NumBits = Load->getMemoryVT().getSizeInBits();
2956 if ((NumBits != 8 && NumBits != 16) ||
2957 NumBits != Load->getMemoryVT().getStoreSizeInBits())
2958 return;
2959
2960 // The load must be an extending one and the constant must be within the
2961 // range of the unextended value.
2962 auto *ConstOp1 = cast<ConstantSDNode>(C.Op1);
2963 if (!ConstOp1 || ConstOp1->getValueSizeInBits(0) > 64)
2964 return;
2965 uint64_t Value = ConstOp1->getZExtValue();
2966 uint64_t Mask = (1 << NumBits) - 1;
2967 if (Load->getExtensionType() == ISD::SEXTLOAD) {
2968 // Make sure that ConstOp1 is in range of C.Op0.
2969 int64_t SignedValue = ConstOp1->getSExtValue();
2970 if (uint64_t(SignedValue) + (uint64_t(1) << (NumBits - 1)) > Mask)
2971 return;
2972 if (C.ICmpType != SystemZICMP::SignedOnly) {
2973 // Unsigned comparison between two sign-extended values is equivalent
2974 // to unsigned comparison between two zero-extended values.
2975 Value &= Mask;
2976 } else if (NumBits == 8) {
2977 // Try to treat the comparison as unsigned, so that we can use CLI.
2978 // Adjust CCMask and Value as necessary.
2979 if (Value == 0 && C.CCMask == SystemZ::CCMASK_CMP_LT)
2980 // Test whether the high bit of the byte is set.
2981 Value = 127, C.CCMask = SystemZ::CCMASK_CMP_GT;
2982 else if (Value == 0 && C.CCMask == SystemZ::CCMASK_CMP_GE)
2983 // Test whether the high bit of the byte is clear.
2984 Value = 128, C.CCMask = SystemZ::CCMASK_CMP_LT;
2985 else
2986 // No instruction exists for this combination.
2987 return;
2988 C.ICmpType = SystemZICMP::UnsignedOnly;
2989 }
2990 } else if (Load->getExtensionType() == ISD::ZEXTLOAD) {
2991 if (Value > Mask)
2992 return;
2993 // If the constant is in range, we can use any comparison.
2994 C.ICmpType = SystemZICMP::Any;
2995 } else
2996 return;
2997
2998 // Make sure that the first operand is an i32 of the right extension type.
2999 ISD::LoadExtType ExtType = (C.ICmpType == SystemZICMP::SignedOnly ?
3002 if (C.Op0.getValueType() != MVT::i32 ||
3003 Load->getExtensionType() != ExtType) {
3004 C.Op0 = DAG.getExtLoad(ExtType, SDLoc(Load), MVT::i32, Load->getChain(),
3005 Load->getBasePtr(), Load->getPointerInfo(),
3006 Load->getMemoryVT(), Load->getAlign(),
3007 Load->getMemOperand()->getFlags());
3008 // Update the chain uses.
3009 DAG.ReplaceAllUsesOfValueWith(SDValue(Load, 1), C.Op0.getValue(1));
3010 }
3011
3012 // Make sure that the second operand is an i32 with the right value.
3013 if (C.Op1.getValueType() != MVT::i32 ||
3014 Value != ConstOp1->getZExtValue())
3015 C.Op1 = DAG.getConstant((uint32_t)Value, DL, MVT::i32);
3016}
3017
3018// Return true if Op is either an unextended load, or a load suitable
3019// for integer register-memory comparisons of type ICmpType.
3020static bool isNaturalMemoryOperand(SDValue Op, unsigned ICmpType) {
3021 auto *Load = dyn_cast<LoadSDNode>(Op.getNode());
3022 if (Load) {
3023 // There are no instructions to compare a register with a memory byte.
3024 if (Load->getMemoryVT() == MVT::i8)
3025 return false;
3026 // Otherwise decide on extension type.
3027 switch (Load->getExtensionType()) {
3028 case ISD::NON_EXTLOAD:
3029 return true;
3030 case ISD::SEXTLOAD:
3031 return ICmpType != SystemZICMP::UnsignedOnly;
3032 case ISD::ZEXTLOAD:
3033 return ICmpType != SystemZICMP::SignedOnly;
3034 default:
3035 break;
3036 }
3037 }
3038 return false;
3039}
3040
3041// Return true if it is better to swap the operands of C.
3042static bool shouldSwapCmpOperands(const Comparison &C) {
3043 // If one side of the compare is a load of the stackguard reference value,
3044 // then that load should be Op1.
3045 if (C.Op0.isMachineOpcode() &&
3046 (C.Op0.getMachineOpcode() == SystemZ::LOAD_STACK_GUARD))
3047 return true;
3048
3049 // Leave i128 and f128 comparisons alone, since they have no memory forms.
3050 if (C.Op0.getValueType() == MVT::i128)
3051 return false;
3052 if (C.Op0.getValueType() == MVT::f128)
3053 return false;
3054
3055 // Always keep a floating-point constant second, since comparisons with
3056 // zero can use LOAD TEST and comparisons with other constants make a
3057 // natural memory operand.
3058 if (isa<ConstantFPSDNode>(C.Op1))
3059 return false;
3060
3061 // Never swap comparisons with zero since there are many ways to optimize
3062 // those later.
3063 auto *ConstOp1 = dyn_cast<ConstantSDNode>(C.Op1);
3064 if (ConstOp1 && ConstOp1->getZExtValue() == 0)
3065 return false;
3066
3067 // Also keep natural memory operands second if the loaded value is
3068 // only used here. Several comparisons have memory forms.
3069 if (isNaturalMemoryOperand(C.Op1, C.ICmpType) && C.Op1.hasOneUse())
3070 return false;
3071
3072 // Look for cases where Cmp0 is a single-use load and Cmp1 isn't.
3073 // In that case we generally prefer the memory to be second.
3074 if (isNaturalMemoryOperand(C.Op0, C.ICmpType) && C.Op0.hasOneUse()) {
3075 // The only exceptions are when the second operand is a constant and
3076 // we can use things like CHHSI.
3077 if (!ConstOp1)
3078 return true;
3079 // The unsigned memory-immediate instructions can handle 16-bit
3080 // unsigned integers.
3081 if (C.ICmpType != SystemZICMP::SignedOnly &&
3082 isUInt<16>(ConstOp1->getZExtValue()))
3083 return false;
3084 // The signed memory-immediate instructions can handle 16-bit
3085 // signed integers.
3086 if (C.ICmpType != SystemZICMP::UnsignedOnly &&
3087 isInt<16>(ConstOp1->getSExtValue()))
3088 return false;
3089 return true;
3090 }
3091
3092 // Try to promote the use of CGFR and CLGFR.
3093 unsigned Opcode0 = C.Op0.getOpcode();
3094 if (C.ICmpType != SystemZICMP::UnsignedOnly && Opcode0 == ISD::SIGN_EXTEND)
3095 return true;
3096 if (C.ICmpType != SystemZICMP::SignedOnly && Opcode0 == ISD::ZERO_EXTEND)
3097 return true;
3098 if (C.ICmpType != SystemZICMP::SignedOnly && Opcode0 == ISD::AND &&
3099 C.Op0.getOperand(1).getOpcode() == ISD::Constant &&
3100 C.Op0.getConstantOperandVal(1) == 0xffffffff)
3101 return true;
3102
3103 return false;
3104}
3105
3106// Check whether C tests for equality between X and Y and whether X - Y
3107// or Y - X is also computed. In that case it's better to compare the
3108// result of the subtraction against zero.
3110 Comparison &C) {
3111 if (C.CCMask == SystemZ::CCMASK_CMP_EQ ||
3112 C.CCMask == SystemZ::CCMASK_CMP_NE) {
3113 for (SDNode *N : C.Op0->users()) {
3114 if (N->getOpcode() == ISD::SUB &&
3115 ((N->getOperand(0) == C.Op0 && N->getOperand(1) == C.Op1) ||
3116 (N->getOperand(0) == C.Op1 && N->getOperand(1) == C.Op0))) {
3117 // Disable the nsw and nuw flags: the backend needs to handle
3118 // overflow as well during comparison elimination.
3119 N->dropFlags(SDNodeFlags::NoWrap);
3120 C.Op0 = SDValue(N, 0);
3121 C.Op1 = DAG.getConstant(0, DL, N->getValueType(0));
3122 return;
3123 }
3124 }
3125 }
3126}
3127
3128// Check whether C compares a floating-point value with zero and if that
3129// floating-point value is also negated. In this case we can use the
3130// negation to set CC, so avoiding separate LOAD AND TEST and
3131// LOAD (NEGATIVE/COMPLEMENT) instructions.
3132static void adjustForFNeg(Comparison &C) {
3133 // This optimization is invalid for strict comparisons, since FNEG
3134 // does not raise any exceptions.
3135 if (C.Chain)
3136 return;
3137 auto *C1 = dyn_cast<ConstantFPSDNode>(C.Op1);
3138 if (C1 && C1->isZero()) {
3139 for (SDNode *N : C.Op0->users()) {
3140 if (N->getOpcode() == ISD::FNEG) {
3141 C.Op0 = SDValue(N, 0);
3142 C.CCMask = SystemZ::reverseCCMask(C.CCMask);
3143 return;
3144 }
3145 }
3146 }
3147}
3148
3149// Check whether C compares (shl X, 32) with 0 and whether X is
3150// also sign-extended. In that case it is better to test the result
3151// of the sign extension using LTGFR.
3152//
3153// This case is important because InstCombine transforms a comparison
3154// with (sext (trunc X)) into a comparison with (shl X, 32).
3155static void adjustForLTGFR(Comparison &C) {
3156 // Check for a comparison between (shl X, 32) and 0.
3157 if (C.Op0.getOpcode() == ISD::SHL && C.Op0.getValueType() == MVT::i64 &&
3158 C.Op1.getOpcode() == ISD::Constant && C.Op1->getAsZExtVal() == 0) {
3159 auto *C1 = dyn_cast<ConstantSDNode>(C.Op0.getOperand(1));
3160 if (C1 && C1->getZExtValue() == 32) {
3161 SDValue ShlOp0 = C.Op0.getOperand(0);
3162 // See whether X has any SIGN_EXTEND_INREG uses.
3163 for (SDNode *N : ShlOp0->users()) {
3164 if (N->getOpcode() == ISD::SIGN_EXTEND_INREG &&
3165 cast<VTSDNode>(N->getOperand(1))->getVT() == MVT::i32) {
3166 C.Op0 = SDValue(N, 0);
3167 return;
3168 }
3169 }
3170 }
3171 }
3172}
3173
3174// If C compares the truncation of an extending load, try to compare
3175// the untruncated value instead. This exposes more opportunities to
3176// reuse CC.
3177static void adjustICmpTruncate(SelectionDAG &DAG, const SDLoc &DL,
3178 Comparison &C) {
3179 if (C.Op0.getOpcode() == ISD::TRUNCATE &&
3180 C.Op0.getOperand(0).getOpcode() == ISD::LOAD &&
3181 C.Op1.getOpcode() == ISD::Constant &&
3182 cast<ConstantSDNode>(C.Op1)->getValueSizeInBits(0) <= 64 &&
3183 C.Op1->getAsZExtVal() == 0) {
3184 auto *L = cast<LoadSDNode>(C.Op0.getOperand(0));
3185 if (L->getMemoryVT().getStoreSizeInBits().getFixedValue() <=
3186 C.Op0.getValueSizeInBits().getFixedValue()) {
3187 unsigned Type = L->getExtensionType();
3188 if ((Type == ISD::ZEXTLOAD && C.ICmpType != SystemZICMP::SignedOnly) ||
3189 (Type == ISD::SEXTLOAD && C.ICmpType != SystemZICMP::UnsignedOnly)) {
3190 C.Op0 = C.Op0.getOperand(0);
3191 C.Op1 = DAG.getConstant(0, DL, C.Op0.getValueType());
3192 }
3193 }
3194 }
3195}
3196
3197// Adjust if a given Compare is a check of the stack guard against a stack
3198// guard instance on the stack. Specifically, this checks if:
3199// - The operands are a load of the stack guard, and a load from a stack slot
3200// - The original opcode is ICMP
3201// - ICMPType is compatible with unsigned comparison.
3203 Comparison &C) {
3204
3205 // Opcode must be ICMP.
3206 if (C.Opcode != SystemZISD::ICMP)
3207 return;
3208 // ICmpType must be Unsigned or Any.
3209 if (C.ICmpType == SystemZICMP::SignedOnly)
3210 return;
3211 // Op0 must be FrameIndex Load.
3212 if (!(ISD::isNormalLoad(C.Op0.getNode()) &&
3213 dyn_cast<FrameIndexSDNode>(C.Op0.getOperand(1))))
3214 return;
3215 // Op1 must be LOAD_STACK_GUARD.
3216 if (!C.Op1.isMachineOpcode() ||
3217 C.Op1.getMachineOpcode() != SystemZ::LOAD_STACK_GUARD)
3218 return;
3219
3220 // At this point we are sure that this is a proper CMP_STACKGUARD
3221 // case, update the opcode to reflect this.
3222 C.Opcode = SystemZISD::CMP_STACKGUARD;
3223 C.Op1 = SDValue();
3224}
3225
3226// Return true if shift operation N has an in-range constant shift value.
3227// Store it in ShiftVal if so.
3228static bool isSimpleShift(SDValue N, unsigned &ShiftVal) {
3229 auto *Shift = dyn_cast<ConstantSDNode>(N.getOperand(1));
3230 if (!Shift)
3231 return false;
3232
3233 uint64_t Amount = Shift->getZExtValue();
3234 if (Amount >= N.getValueSizeInBits())
3235 return false;
3236
3237 ShiftVal = Amount;
3238 return true;
3239}
3240
3241// Check whether an AND with Mask is suitable for a TEST UNDER MASK
3242// instruction and whether the CC value is descriptive enough to handle
3243// a comparison of type Opcode between the AND result and CmpVal.
3244// CCMask says which comparison result is being tested and BitSize is
3245// the number of bits in the operands. If TEST UNDER MASK can be used,
3246// return the corresponding CC mask, otherwise return 0.
3247static unsigned getTestUnderMaskCond(unsigned BitSize, unsigned CCMask,
3248 uint64_t Mask, uint64_t CmpVal,
3249 unsigned ICmpType) {
3250 assert(Mask != 0 && "ANDs with zero should have been removed by now");
3251
3252 // Check whether the mask is suitable for TMHH, TMHL, TMLH or TMLL.
3253 if (!SystemZ::isImmLL(Mask) && !SystemZ::isImmLH(Mask) &&
3254 !SystemZ::isImmHL(Mask) && !SystemZ::isImmHH(Mask))
3255 return 0;
3256
3257 // Work out the masks for the lowest and highest bits.
3259 uint64_t Low = uint64_t(1) << llvm::countr_zero(Mask);
3260
3261 // Signed ordered comparisons are effectively unsigned if the sign
3262 // bit is dropped.
3263 bool EffectivelyUnsigned = (ICmpType != SystemZICMP::SignedOnly);
3264
3265 // Check for equality comparisons with 0, or the equivalent.
3266 if (CmpVal == 0) {
3267 if (CCMask == SystemZ::CCMASK_CMP_EQ)
3269 if (CCMask == SystemZ::CCMASK_CMP_NE)
3271 }
3272 if (EffectivelyUnsigned && CmpVal > 0 && CmpVal <= Low) {
3273 if (CCMask == SystemZ::CCMASK_CMP_LT)
3275 if (CCMask == SystemZ::CCMASK_CMP_GE)
3277 }
3278 if (EffectivelyUnsigned && CmpVal < Low) {
3279 if (CCMask == SystemZ::CCMASK_CMP_LE)
3281 if (CCMask == SystemZ::CCMASK_CMP_GT)
3283 }
3284
3285 // Check for equality comparisons with the mask, or the equivalent.
3286 if (CmpVal == Mask) {
3287 if (CCMask == SystemZ::CCMASK_CMP_EQ)
3289 if (CCMask == SystemZ::CCMASK_CMP_NE)
3291 }
3292 if (EffectivelyUnsigned && CmpVal >= Mask - Low && CmpVal < Mask) {
3293 if (CCMask == SystemZ::CCMASK_CMP_GT)
3295 if (CCMask == SystemZ::CCMASK_CMP_LE)
3297 }
3298 if (EffectivelyUnsigned && CmpVal > Mask - Low && CmpVal <= Mask) {
3299 if (CCMask == SystemZ::CCMASK_CMP_GE)
3301 if (CCMask == SystemZ::CCMASK_CMP_LT)
3303 }
3304
3305 // Check for ordered comparisons with the top bit.
3306 if (EffectivelyUnsigned && CmpVal >= Mask - High && CmpVal < High) {
3307 if (CCMask == SystemZ::CCMASK_CMP_LE)
3309 if (CCMask == SystemZ::CCMASK_CMP_GT)
3311 }
3312 if (EffectivelyUnsigned && CmpVal > Mask - High && CmpVal <= High) {
3313 if (CCMask == SystemZ::CCMASK_CMP_LT)
3315 if (CCMask == SystemZ::CCMASK_CMP_GE)
3317 }
3318
3319 // If there are just two bits, we can do equality checks for Low and High
3320 // as well.
3321 if (Mask == Low + High) {
3322 if (CCMask == SystemZ::CCMASK_CMP_EQ && CmpVal == Low)
3324 if (CCMask == SystemZ::CCMASK_CMP_NE && CmpVal == Low)
3326 if (CCMask == SystemZ::CCMASK_CMP_EQ && CmpVal == High)
3328 if (CCMask == SystemZ::CCMASK_CMP_NE && CmpVal == High)
3330 }
3331
3332 // Looks like we've exhausted our options.
3333 return 0;
3334}
3335
3336// See whether C can be implemented as a TEST UNDER MASK instruction.
3337// Update the arguments with the TM version if so.
3339 Comparison &C) {
3340 // Use VECTOR TEST UNDER MASK for i128 operations.
3341 if (C.Op0.getValueType() == MVT::i128) {
3342 // We can use VTM for EQ/NE comparisons of x & y against 0.
3343 if (C.Op0.getOpcode() == ISD::AND &&
3344 (C.CCMask == SystemZ::CCMASK_CMP_EQ ||
3345 C.CCMask == SystemZ::CCMASK_CMP_NE)) {
3346 auto *Mask = dyn_cast<ConstantSDNode>(C.Op1);
3347 if (Mask && Mask->getAPIntValue() == 0) {
3348 C.Opcode = SystemZISD::VTM;
3349 C.Op1 = DAG.getNode(ISD::BITCAST, DL, MVT::v16i8, C.Op0.getOperand(1));
3350 C.Op0 = DAG.getNode(ISD::BITCAST, DL, MVT::v16i8, C.Op0.getOperand(0));
3351 C.CCValid = SystemZ::CCMASK_VCMP;
3352 if (C.CCMask == SystemZ::CCMASK_CMP_EQ)
3353 C.CCMask = SystemZ::CCMASK_VCMP_ALL;
3354 else
3355 C.CCMask = SystemZ::CCMASK_VCMP_ALL ^ C.CCValid;
3356 }
3357 }
3358 return;
3359 }
3360
3361 // Check that we have a comparison with a constant.
3362 auto *ConstOp1 = dyn_cast<ConstantSDNode>(C.Op1);
3363 if (!ConstOp1)
3364 return;
3365 uint64_t CmpVal = ConstOp1->getZExtValue();
3366
3367 // Check whether the nonconstant input is an AND with a constant mask.
3368 Comparison NewC(C);
3369 uint64_t MaskVal;
3370 ConstantSDNode *Mask = nullptr;
3371 if (C.Op0.getOpcode() == ISD::AND) {
3372 NewC.Op0 = C.Op0.getOperand(0);
3373 NewC.Op1 = C.Op0.getOperand(1);
3374 Mask = dyn_cast<ConstantSDNode>(NewC.Op1);
3375 if (!Mask)
3376 return;
3377 MaskVal = Mask->getZExtValue();
3378 } else {
3379 // There is no instruction to compare with a 64-bit immediate
3380 // so use TMHH instead if possible. We need an unsigned ordered
3381 // comparison with an i64 immediate.
3382 if (NewC.Op0.getValueType() != MVT::i64 ||
3383 NewC.CCMask == SystemZ::CCMASK_CMP_EQ ||
3384 NewC.CCMask == SystemZ::CCMASK_CMP_NE ||
3385 NewC.ICmpType == SystemZICMP::SignedOnly)
3386 return;
3387 // Convert LE and GT comparisons into LT and GE.
3388 if (NewC.CCMask == SystemZ::CCMASK_CMP_LE ||
3389 NewC.CCMask == SystemZ::CCMASK_CMP_GT) {
3390 if (CmpVal == uint64_t(-1))
3391 return;
3392 CmpVal += 1;
3393 NewC.CCMask ^= SystemZ::CCMASK_CMP_EQ;
3394 }
3395 // If the low N bits of Op1 are zero than the low N bits of Op0 can
3396 // be masked off without changing the result.
3397 MaskVal = -(CmpVal & -CmpVal);
3398 NewC.ICmpType = SystemZICMP::UnsignedOnly;
3399 }
3400 if (!MaskVal)
3401 return;
3402
3403 // Check whether the combination of mask, comparison value and comparison
3404 // type are suitable.
3405 unsigned BitSize = NewC.Op0.getValueSizeInBits();
3406 unsigned NewCCMask, ShiftVal;
3407 if (NewC.ICmpType != SystemZICMP::SignedOnly &&
3408 NewC.Op0.getOpcode() == ISD::SHL &&
3409 isSimpleShift(NewC.Op0, ShiftVal) &&
3410 (MaskVal >> ShiftVal != 0) &&
3411 ((CmpVal >> ShiftVal) << ShiftVal) == CmpVal &&
3412 (NewCCMask = getTestUnderMaskCond(BitSize, NewC.CCMask,
3413 MaskVal >> ShiftVal,
3414 CmpVal >> ShiftVal,
3415 SystemZICMP::Any))) {
3416 NewC.Op0 = NewC.Op0.getOperand(0);
3417 MaskVal >>= ShiftVal;
3418 } else if (NewC.ICmpType != SystemZICMP::SignedOnly &&
3419 NewC.Op0.getOpcode() == ISD::SRL &&
3420 isSimpleShift(NewC.Op0, ShiftVal) &&
3421 (MaskVal << ShiftVal != 0) &&
3422 ((CmpVal << ShiftVal) >> ShiftVal) == CmpVal &&
3423 (NewCCMask = getTestUnderMaskCond(BitSize, NewC.CCMask,
3424 MaskVal << ShiftVal,
3425 CmpVal << ShiftVal,
3427 NewC.Op0 = NewC.Op0.getOperand(0);
3428 MaskVal <<= ShiftVal;
3429 } else {
3430 NewCCMask = getTestUnderMaskCond(BitSize, NewC.CCMask, MaskVal, CmpVal,
3431 NewC.ICmpType);
3432 if (!NewCCMask)
3433 return;
3434 }
3435
3436 // Go ahead and make the change.
3437 C.Opcode = SystemZISD::TM;
3438 C.Op0 = NewC.Op0;
3439 if (Mask && Mask->getZExtValue() == MaskVal)
3440 C.Op1 = SDValue(Mask, 0);
3441 else
3442 C.Op1 = DAG.getConstant(MaskVal, DL, C.Op0.getValueType());
3443 C.CCValid = SystemZ::CCMASK_TM;
3444 C.CCMask = NewCCMask;
3445}
3446
3447// Implement i128 comparison in vector registers.
3448static void adjustICmp128(SelectionDAG &DAG, const SDLoc &DL,
3449 Comparison &C) {
3450 if (C.Opcode != SystemZISD::ICMP)
3451 return;
3452 if (C.Op0.getValueType() != MVT::i128)
3453 return;
3454
3455 // Recognize vector comparison reductions.
3456 if ((C.CCMask == SystemZ::CCMASK_CMP_EQ ||
3457 C.CCMask == SystemZ::CCMASK_CMP_NE) &&
3458 (isNullConstant(C.Op1) || isAllOnesConstant(C.Op1))) {
3459 bool CmpEq = C.CCMask == SystemZ::CCMASK_CMP_EQ;
3460 bool CmpNull = isNullConstant(C.Op1);
3461 SDValue Src = peekThroughBitcasts(C.Op0);
3462 if (Src.hasOneUse() && isBitwiseNot(Src)) {
3463 Src = Src.getOperand(0);
3464 CmpNull = !CmpNull;
3465 }
3466 unsigned Opcode = 0;
3467 if (Src.hasOneUse()) {
3468 switch (Src.getOpcode()) {
3469 case SystemZISD::VICMPE: Opcode = SystemZISD::VICMPES; break;
3470 case SystemZISD::VICMPH: Opcode = SystemZISD::VICMPHS; break;
3471 case SystemZISD::VICMPHL: Opcode = SystemZISD::VICMPHLS; break;
3472 case SystemZISD::VFCMPE: Opcode = SystemZISD::VFCMPES; break;
3473 case SystemZISD::VFCMPH: Opcode = SystemZISD::VFCMPHS; break;
3474 case SystemZISD::VFCMPHE: Opcode = SystemZISD::VFCMPHES; break;
3475 default: break;
3476 }
3477 }
3478 if (Opcode) {
3479 C.Opcode = Opcode;
3480 C.Op0 = Src->getOperand(0);
3481 C.Op1 = Src->getOperand(1);
3482 C.CCValid = SystemZ::CCMASK_VCMP;
3484 if (!CmpEq)
3485 C.CCMask ^= C.CCValid;
3486 return;
3487 }
3488 }
3489
3490 // Everything below here is not useful if we have native i128 compares.
3491 if (DAG.getSubtarget<SystemZSubtarget>().hasVectorEnhancements3())
3492 return;
3493
3494 // (In-)Equality comparisons can be implemented via VCEQGS.
3495 if (C.CCMask == SystemZ::CCMASK_CMP_EQ ||
3496 C.CCMask == SystemZ::CCMASK_CMP_NE) {
3497 C.Opcode = SystemZISD::VICMPES;
3498 C.Op0 = DAG.getNode(ISD::BITCAST, DL, MVT::v2i64, C.Op0);
3499 C.Op1 = DAG.getNode(ISD::BITCAST, DL, MVT::v2i64, C.Op1);
3500 C.CCValid = SystemZ::CCMASK_VCMP;
3501 if (C.CCMask == SystemZ::CCMASK_CMP_EQ)
3502 C.CCMask = SystemZ::CCMASK_VCMP_ALL;
3503 else
3504 C.CCMask = SystemZ::CCMASK_VCMP_ALL ^ C.CCValid;
3505 return;
3506 }
3507
3508 // Normalize other comparisons to GT.
3509 bool Swap = false, Invert = false;
3510 switch (C.CCMask) {
3511 case SystemZ::CCMASK_CMP_GT: break;
3512 case SystemZ::CCMASK_CMP_LT: Swap = true; break;
3513 case SystemZ::CCMASK_CMP_LE: Invert = true; break;
3514 case SystemZ::CCMASK_CMP_GE: Swap = Invert = true; break;
3515 default: llvm_unreachable("Invalid integer condition!");
3516 }
3517 if (Swap)
3518 std::swap(C.Op0, C.Op1);
3519
3520 if (C.ICmpType == SystemZICMP::UnsignedOnly)
3521 C.Opcode = SystemZISD::UCMP128HI;
3522 else
3523 C.Opcode = SystemZISD::SCMP128HI;
3524 C.CCValid = SystemZ::CCMASK_ANY;
3525 C.CCMask = SystemZ::CCMASK_1;
3526
3527 if (Invert)
3528 C.CCMask ^= C.CCValid;
3529}
3530
3531// See whether the comparison argument contains a redundant AND
3532// and remove it if so. This sometimes happens due to the generic
3533// BRCOND expansion.
3535 Comparison &C) {
3536 if (C.Op0.getOpcode() != ISD::AND)
3537 return;
3538 auto *Mask = dyn_cast<ConstantSDNode>(C.Op0.getOperand(1));
3539 if (!Mask || Mask->getValueSizeInBits(0) > 64)
3540 return;
3541 KnownBits Known = DAG.computeKnownBits(C.Op0.getOperand(0));
3542 if ((~Known.Zero).getZExtValue() & ~Mask->getZExtValue())
3543 return;
3544
3545 C.Op0 = C.Op0.getOperand(0);
3546}
3547
3548// Return a Comparison that tests the condition-code result of intrinsic
3549// node Call against constant integer CC using comparison code Cond.
3550// Opcode is the opcode of the SystemZISD operation for the intrinsic
3551// and CCValid is the set of possible condition-code results.
3552static Comparison getIntrinsicCmp(SelectionDAG &DAG, unsigned Opcode,
3553 SDValue Call, unsigned CCValid, uint64_t CC,
3555 Comparison C(Call, SDValue(), SDValue());
3556 C.Opcode = Opcode;
3557 C.CCValid = CCValid;
3558 if (Cond == ISD::SETEQ)
3559 // bit 3 for CC==0, bit 0 for CC==3, always false for CC>3.
3560 C.CCMask = CC < 4 ? 1 << (3 - CC) : 0;
3561 else if (Cond == ISD::SETNE)
3562 // ...and the inverse of that.
3563 C.CCMask = CC < 4 ? ~(1 << (3 - CC)) : -1;
3564 else if (Cond == ISD::SETLT || Cond == ISD::SETULT)
3565 // bits above bit 3 for CC==0 (always false), bits above bit 0 for CC==3,
3566 // always true for CC>3.
3567 C.CCMask = CC < 4 ? ~0U << (4 - CC) : -1;
3568 else if (Cond == ISD::SETGE || Cond == ISD::SETUGE)
3569 // ...and the inverse of that.
3570 C.CCMask = CC < 4 ? ~(~0U << (4 - CC)) : 0;
3571 else if (Cond == ISD::SETLE || Cond == ISD::SETULE)
3572 // bit 3 and above for CC==0, bit 0 and above for CC==3 (always true),
3573 // always true for CC>3.
3574 C.CCMask = CC < 4 ? ~0U << (3 - CC) : -1;
3575 else if (Cond == ISD::SETGT || Cond == ISD::SETUGT)
3576 // ...and the inverse of that.
3577 C.CCMask = CC < 4 ? ~(~0U << (3 - CC)) : 0;
3578 else
3579 llvm_unreachable("Unexpected integer comparison type");
3580 C.CCMask &= CCValid;
3581 return C;
3582}
3583
3584// Decide how to implement a comparison of type Cond between CmpOp0 with CmpOp1.
3585static Comparison getCmp(SelectionDAG &DAG, SDValue CmpOp0, SDValue CmpOp1,
3586 ISD::CondCode Cond, const SDLoc &DL,
3587 SDValue Chain = SDValue(),
3588 bool IsSignaling = false) {
3589 if (CmpOp1.getOpcode() == ISD::Constant) {
3590 assert(!Chain);
3591 unsigned Opcode, CCValid;
3592 if (CmpOp0.getOpcode() == ISD::INTRINSIC_W_CHAIN &&
3593 CmpOp0.getResNo() == 0 && CmpOp0->hasNUsesOfValue(1, 0) &&
3594 isIntrinsicWithCCAndChain(CmpOp0, Opcode, CCValid))
3595 return getIntrinsicCmp(DAG, Opcode, CmpOp0, CCValid,
3596 CmpOp1->getAsZExtVal(), Cond);
3597 if (CmpOp0.getOpcode() == ISD::INTRINSIC_WO_CHAIN &&
3598 CmpOp0.getResNo() == CmpOp0->getNumValues() - 1 &&
3599 isIntrinsicWithCC(CmpOp0, Opcode, CCValid))
3600 return getIntrinsicCmp(DAG, Opcode, CmpOp0, CCValid,
3601 CmpOp1->getAsZExtVal(), Cond);
3602 }
3603 Comparison C(CmpOp0, CmpOp1, Chain);
3604 C.CCMask = CCMaskForCondCode(Cond);
3605 if (C.Op0.getValueType().isFloatingPoint()) {
3606 C.CCValid = SystemZ::CCMASK_FCMP;
3607 if (!C.Chain)
3608 C.Opcode = SystemZISD::FCMP;
3609 else if (!IsSignaling)
3610 C.Opcode = SystemZISD::STRICT_FCMP;
3611 else
3612 C.Opcode = SystemZISD::STRICT_FCMPS;
3614 } else {
3615 assert(!C.Chain);
3616 C.CCValid = SystemZ::CCMASK_ICMP;
3617 C.Opcode = SystemZISD::ICMP;
3618 // Choose the type of comparison. Equality and inequality tests can
3619 // use either signed or unsigned comparisons. The choice also doesn't
3620 // matter if both sign bits are known to be clear. In those cases we
3621 // want to give the main isel code the freedom to choose whichever
3622 // form fits best.
3623 if (C.CCMask == SystemZ::CCMASK_CMP_EQ ||
3624 C.CCMask == SystemZ::CCMASK_CMP_NE ||
3625 (DAG.SignBitIsZero(C.Op0) && DAG.SignBitIsZero(C.Op1)))
3626 C.ICmpType = SystemZICMP::Any;
3627 else if (C.CCMask & SystemZ::CCMASK_CMP_UO)
3628 C.ICmpType = SystemZICMP::UnsignedOnly;
3629 else
3630 C.ICmpType = SystemZICMP::SignedOnly;
3631 C.CCMask &= ~SystemZ::CCMASK_CMP_UO;
3632 adjustForRedundantAnd(DAG, DL, C);
3633 adjustZeroCmp(DAG, DL, C);
3634 adjustSubwordCmp(DAG, DL, C);
3635 adjustForSubtraction(DAG, DL, C);
3637 adjustICmpTruncate(DAG, DL, C);
3638 }
3639
3640 if (shouldSwapCmpOperands(C)) {
3641 std::swap(C.Op0, C.Op1);
3642 C.CCMask = SystemZ::reverseCCMask(C.CCMask);
3643 }
3644
3646 adjustICmp128(DAG, DL, C);
3648 return C;
3649}
3650
3651// Emit the comparison instruction described by C.
3652static SDValue emitCmp(SelectionDAG &DAG, const SDLoc &DL, Comparison &C) {
3653 if (!C.Op1.getNode()) {
3654 if (C.Opcode == SystemZISD::CMP_STACKGUARD)
3655 return DAG.getNode(SystemZISD::CMP_STACKGUARD, DL, MVT::i32, C.Op0);
3656 SDNode *Node;
3657 switch (C.Op0.getOpcode()) {
3659 Node = emitIntrinsicWithCCAndChain(DAG, C.Op0, C.Opcode);
3660 return SDValue(Node, 0);
3662 Node = emitIntrinsicWithCC(DAG, C.Op0, C.Opcode);
3663 return SDValue(Node, Node->getNumValues() - 1);
3664 default:
3665 llvm_unreachable("Invalid comparison operands");
3666 }
3667 }
3668 if (C.Opcode == SystemZISD::ICMP)
3669 return DAG.getNode(SystemZISD::ICMP, DL, MVT::i32, C.Op0, C.Op1,
3670 DAG.getTargetConstant(C.ICmpType, DL, MVT::i32));
3671 if (C.Opcode == SystemZISD::TM) {
3672 bool RegisterOnly = (bool(C.CCMask & SystemZ::CCMASK_TM_MIXED_MSB_0) !=
3674 return DAG.getNode(SystemZISD::TM, DL, MVT::i32, C.Op0, C.Op1,
3675 DAG.getTargetConstant(RegisterOnly, DL, MVT::i32));
3676 }
3677 if (C.Opcode == SystemZISD::VICMPES ||
3678 C.Opcode == SystemZISD::VICMPHS ||
3679 C.Opcode == SystemZISD::VICMPHLS ||
3680 C.Opcode == SystemZISD::VFCMPES ||
3681 C.Opcode == SystemZISD::VFCMPHS ||
3682 C.Opcode == SystemZISD::VFCMPHES) {
3683 EVT IntVT = C.Op0.getValueType().changeVectorElementTypeToInteger();
3684 SDVTList VTs = DAG.getVTList(IntVT, MVT::i32);
3685 SDValue Val = DAG.getNode(C.Opcode, DL, VTs, C.Op0, C.Op1);
3686 return SDValue(Val.getNode(), 1);
3687 }
3688 if (C.Chain) {
3689 SDVTList VTs = DAG.getVTList(MVT::i32, MVT::Other);
3690 return DAG.getNode(C.Opcode, DL, VTs, C.Chain, C.Op0, C.Op1);
3691 }
3692 return DAG.getNode(C.Opcode, DL, MVT::i32, C.Op0, C.Op1);
3693}
3694
3695// Implement a 32-bit *MUL_LOHI operation by extending both operands to
3696// 64 bits. Extend is the extension type to use. Store the high part
3697// in Hi and the low part in Lo.
3698static void lowerMUL_LOHI32(SelectionDAG &DAG, const SDLoc &DL, unsigned Extend,
3699 SDValue Op0, SDValue Op1, SDValue &Hi,
3700 SDValue &Lo) {
3701 Op0 = DAG.getNode(Extend, DL, MVT::i64, Op0);
3702 Op1 = DAG.getNode(Extend, DL, MVT::i64, Op1);
3703 SDValue Mul = DAG.getNode(ISD::MUL, DL, MVT::i64, Op0, Op1);
3704 Hi = DAG.getNode(ISD::SRL, DL, MVT::i64, Mul,
3705 DAG.getConstant(32, DL, MVT::i64));
3706 Hi = DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Hi);
3707 Lo = DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Mul);
3708}
3709
3710// Lower a binary operation that produces two VT results, one in each
3711// half of a GR128 pair. Op0 and Op1 are the VT operands to the operation,
3712// and Opcode performs the GR128 operation. Store the even register result
3713// in Even and the odd register result in Odd.
3714static void lowerGR128Binary(SelectionDAG &DAG, const SDLoc &DL, EVT VT,
3715 unsigned Opcode, SDValue Op0, SDValue Op1,
3716 SDValue &Even, SDValue &Odd) {
3717 SDValue Result = DAG.getNode(Opcode, DL, MVT::Untyped, Op0, Op1);
3718 bool Is32Bit = is32Bit(VT);
3719 Even = DAG.getTargetExtractSubreg(SystemZ::even128(Is32Bit), DL, VT, Result);
3720 Odd = DAG.getTargetExtractSubreg(SystemZ::odd128(Is32Bit), DL, VT, Result);
3721}
3722
3723// Return an i32 value that is 1 if the CC value produced by CCReg is
3724// in the mask CCMask and 0 otherwise. CC is known to have a value
3725// in CCValid, so other values can be ignored.
3726static SDValue emitSETCC(SelectionDAG &DAG, const SDLoc &DL, SDValue CCReg,
3727 unsigned CCValid, unsigned CCMask) {
3728 SDValue Ops[] = {DAG.getConstant(1, DL, MVT::i32),
3729 DAG.getConstant(0, DL, MVT::i32),
3730 DAG.getTargetConstant(CCValid, DL, MVT::i32),
3731 DAG.getTargetConstant(CCMask, DL, MVT::i32), CCReg};
3732 return DAG.getNode(SystemZISD::SELECT_CCMASK, DL, MVT::i32, Ops);
3733}
3734
3735// Return the SystemISD vector comparison operation for CC, or 0 if it cannot
3736// be done directly. Mode is CmpMode::Int for integer comparisons, CmpMode::FP
3737// for regular floating-point comparisons, CmpMode::StrictFP for strict (quiet)
3738// floating-point comparisons, and CmpMode::SignalingFP for strict signaling
3739// floating-point comparisons.
3742 switch (CC) {
3743 case ISD::SETOEQ:
3744 case ISD::SETEQ:
3745 switch (Mode) {
3746 case CmpMode::Int: return SystemZISD::VICMPE;
3747 case CmpMode::FP: return SystemZISD::VFCMPE;
3748 case CmpMode::StrictFP: return SystemZISD::STRICT_VFCMPE;
3749 case CmpMode::SignalingFP: return SystemZISD::STRICT_VFCMPES;
3750 }
3751 llvm_unreachable("Bad mode");
3752
3753 case ISD::SETOGE:
3754 case ISD::SETGE:
3755 switch (Mode) {
3756 case CmpMode::Int: return 0;
3757 case CmpMode::FP: return SystemZISD::VFCMPHE;
3758 case CmpMode::StrictFP: return SystemZISD::STRICT_VFCMPHE;
3759 case CmpMode::SignalingFP: return SystemZISD::STRICT_VFCMPHES;
3760 }
3761 llvm_unreachable("Bad mode");
3762
3763 case ISD::SETOGT:
3764 case ISD::SETGT:
3765 switch (Mode) {
3766 case CmpMode::Int: return SystemZISD::VICMPH;
3767 case CmpMode::FP: return SystemZISD::VFCMPH;
3768 case CmpMode::StrictFP: return SystemZISD::STRICT_VFCMPH;
3769 case CmpMode::SignalingFP: return SystemZISD::STRICT_VFCMPHS;
3770 }
3771 llvm_unreachable("Bad mode");
3772
3773 case ISD::SETUGT:
3774 switch (Mode) {
3775 case CmpMode::Int: return SystemZISD::VICMPHL;
3776 case CmpMode::FP: return 0;
3777 case CmpMode::StrictFP: return 0;
3778 case CmpMode::SignalingFP: return 0;
3779 }
3780 llvm_unreachable("Bad mode");
3781
3782 default:
3783 return 0;
3784 }
3785}
3786
3787// Return the SystemZISD vector comparison operation for CC or its inverse,
3788// or 0 if neither can be done directly. Indicate in Invert whether the
3789// result is for the inverse of CC. Mode is as above.
3791 bool &Invert) {
3792 if (unsigned Opcode = getVectorComparison(CC, Mode)) {
3793 Invert = false;
3794 return Opcode;
3795 }
3796
3797 CC = ISD::getSetCCInverse(CC, Mode == CmpMode::Int ? MVT::i32 : MVT::f32);
3798 if (unsigned Opcode = getVectorComparison(CC, Mode)) {
3799 Invert = true;
3800 return Opcode;
3801 }
3802
3803 return 0;
3804}
3805
3806// Return a v2f64 that contains the extended form of elements Start and Start+1
3807// of v4f32 value Op. If Chain is nonnull, return the strict form.
3808static SDValue expandV4F32ToV2F64(SelectionDAG &DAG, int Start, const SDLoc &DL,
3809 SDValue Op, SDValue Chain) {
3810 int Mask[] = { Start, -1, Start + 1, -1 };
3811 Op = DAG.getVectorShuffle(MVT::v4f32, DL, Op, DAG.getUNDEF(MVT::v4f32), Mask);
3812 if (Chain) {
3813 SDVTList VTs = DAG.getVTList(MVT::v2f64, MVT::Other);
3814 return DAG.getNode(SystemZISD::STRICT_VEXTEND, DL, VTs, Chain, Op);
3815 }
3816 return DAG.getNode(SystemZISD::VEXTEND, DL, MVT::v2f64, Op);
3817}
3818
3819// Build a comparison of vectors CmpOp0 and CmpOp1 using opcode Opcode,
3820// producing a result of type VT. If Chain is nonnull, return the strict form.
3821SDValue SystemZTargetLowering::getVectorCmp(SelectionDAG &DAG, unsigned Opcode,
3822 const SDLoc &DL, EVT VT,
3823 SDValue CmpOp0,
3824 SDValue CmpOp1,
3825 SDValue Chain) const {
3826 // There is no hardware support for v4f32 (unless we have the vector
3827 // enhancements facility 1), so extend the vector into two v2f64s
3828 // and compare those.
3829 if (CmpOp0.getValueType() == MVT::v4f32 &&
3830 !Subtarget.hasVectorEnhancements1()) {
3831 SDValue H0 = expandV4F32ToV2F64(DAG, 0, DL, CmpOp0, Chain);
3832 SDValue L0 = expandV4F32ToV2F64(DAG, 2, DL, CmpOp0, Chain);
3833 SDValue H1 = expandV4F32ToV2F64(DAG, 0, DL, CmpOp1, Chain);
3834 SDValue L1 = expandV4F32ToV2F64(DAG, 2, DL, CmpOp1, Chain);
3835 if (Chain) {
3836 SDVTList VTs = DAG.getVTList(MVT::v2i64, MVT::Other);
3837 SDValue HRes = DAG.getNode(Opcode, DL, VTs, Chain, H0, H1);
3838 SDValue LRes = DAG.getNode(Opcode, DL, VTs, Chain, L0, L1);
3839 SDValue Res = DAG.getNode(SystemZISD::PACK, DL, VT, HRes, LRes);
3840 SDValue Chains[6] = { H0.getValue(1), L0.getValue(1),
3841 H1.getValue(1), L1.getValue(1),
3842 HRes.getValue(1), LRes.getValue(1) };
3843 SDValue NewChain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Chains);
3844 SDValue Ops[2] = { Res, NewChain };
3845 return DAG.getMergeValues(Ops, DL);
3846 }
3847 SDValue HRes = DAG.getNode(Opcode, DL, MVT::v2i64, H0, H1);
3848 SDValue LRes = DAG.getNode(Opcode, DL, MVT::v2i64, L0, L1);
3849 return DAG.getNode(SystemZISD::PACK, DL, VT, HRes, LRes);
3850 }
3851 if (Chain) {
3852 SDVTList VTs = DAG.getVTList(VT, MVT::Other);
3853 return DAG.getNode(Opcode, DL, VTs, Chain, CmpOp0, CmpOp1);
3854 }
3855 return DAG.getNode(Opcode, DL, VT, CmpOp0, CmpOp1);
3856}
3857
3858// Lower a vector comparison of type CC between CmpOp0 and CmpOp1, producing
3859// an integer mask of type VT. If Chain is nonnull, we have a strict
3860// floating-point comparison. If in addition IsSignaling is true, we have
3861// a strict signaling floating-point comparison.
3862SDValue SystemZTargetLowering::lowerVectorSETCC(SelectionDAG &DAG,
3863 const SDLoc &DL, EVT VT,
3864 ISD::CondCode CC,
3865 SDValue CmpOp0,
3866 SDValue CmpOp1,
3867 SDValue Chain,
3868 bool IsSignaling) const {
3869 bool IsFP = CmpOp0.getValueType().isFloatingPoint();
3870 assert (!Chain || IsFP);
3871 assert (!IsSignaling || Chain);
3872 CmpMode Mode = IsSignaling ? CmpMode::SignalingFP :
3873 Chain ? CmpMode::StrictFP : IsFP ? CmpMode::FP : CmpMode::Int;
3874 bool Invert = false;
3875 SDValue Cmp;
3876 switch (CC) {
3877 // Handle tests for order using (or (ogt y x) (oge x y)).
3878 case ISD::SETUO:
3879 Invert = true;
3880 [[fallthrough]];
3881 case ISD::SETO: {
3882 assert(IsFP && "Unexpected integer comparison");
3883 SDValue LT = getVectorCmp(DAG, getVectorComparison(ISD::SETOGT, Mode),
3884 DL, VT, CmpOp1, CmpOp0, Chain);
3885 SDValue GE = getVectorCmp(DAG, getVectorComparison(ISD::SETOGE, Mode),
3886 DL, VT, CmpOp0, CmpOp1, Chain);
3887 Cmp = DAG.getNode(ISD::OR, DL, VT, LT, GE);
3888 if (Chain)
3889 Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other,
3890 LT.getValue(1), GE.getValue(1));
3891 break;
3892 }
3893
3894 // Handle <> tests using (or (ogt y x) (ogt x y)).
3895 case ISD::SETUEQ:
3896 Invert = true;
3897 [[fallthrough]];
3898 case ISD::SETONE: {
3899 assert(IsFP && "Unexpected integer comparison");
3900 SDValue LT = getVectorCmp(DAG, getVectorComparison(ISD::SETOGT, Mode),
3901 DL, VT, CmpOp1, CmpOp0, Chain);
3902 SDValue GT = getVectorCmp(DAG, getVectorComparison(ISD::SETOGT, Mode),
3903 DL, VT, CmpOp0, CmpOp1, Chain);
3904 Cmp = DAG.getNode(ISD::OR, DL, VT, LT, GT);
3905 if (Chain)
3906 Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other,
3907 LT.getValue(1), GT.getValue(1));
3908 break;
3909 }
3910
3911 // Otherwise a single comparison is enough. It doesn't really
3912 // matter whether we try the inversion or the swap first, since
3913 // there are no cases where both work.
3914 default:
3915 // Optimize sign-bit comparisons to signed compares.
3916 if (Mode == CmpMode::Int && (CC == ISD::SETEQ || CC == ISD::SETNE) &&
3918 unsigned EltSize = VT.getVectorElementType().getSizeInBits();
3919 APInt Mask;
3920 if (CmpOp0.getOpcode() == ISD::AND
3921 && ISD::isConstantSplatVector(CmpOp0.getOperand(1).getNode(), Mask)
3922 && Mask == APInt::getSignMask(EltSize)) {
3923 CC = CC == ISD::SETEQ ? ISD::SETGE : ISD::SETLT;
3924 CmpOp0 = CmpOp0.getOperand(0);
3925 }
3926 }
3927 if (unsigned Opcode = getVectorComparisonOrInvert(CC, Mode, Invert))
3928 Cmp = getVectorCmp(DAG, Opcode, DL, VT, CmpOp0, CmpOp1, Chain);
3929 else {
3931 if (unsigned Opcode = getVectorComparisonOrInvert(CC, Mode, Invert))
3932 Cmp = getVectorCmp(DAG, Opcode, DL, VT, CmpOp1, CmpOp0, Chain);
3933 else
3934 llvm_unreachable("Unhandled comparison");
3935 }
3936 if (Chain)
3937 Chain = Cmp.getValue(1);
3938 break;
3939 }
3940 if (Invert) {
3941 SDValue Mask =
3942 DAG.getSplatBuildVector(VT, DL, DAG.getAllOnesConstant(DL, MVT::i64));
3943 Cmp = DAG.getNode(ISD::XOR, DL, VT, Cmp, Mask);
3944 }
3945 if (Chain && Chain.getNode() != Cmp.getNode()) {
3946 SDValue Ops[2] = { Cmp, Chain };
3947 Cmp = DAG.getMergeValues(Ops, DL);
3948 }
3949 return Cmp;
3950}
3951
3952SDValue SystemZTargetLowering::lowerSETCC(SDValue Op,
3953 SelectionDAG &DAG) const {
3954 SDValue CmpOp0 = Op.getOperand(0);
3955 SDValue CmpOp1 = Op.getOperand(1);
3956 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(2))->get();
3957 SDLoc DL(Op);
3958 EVT VT = Op.getValueType();
3959 if (VT.isVector())
3960 return lowerVectorSETCC(DAG, DL, VT, CC, CmpOp0, CmpOp1);
3961
3962 Comparison C(getCmp(DAG, CmpOp0, CmpOp1, CC, DL));
3963 SDValue CCReg = emitCmp(DAG, DL, C);
3964 return emitSETCC(DAG, DL, CCReg, C.CCValid, C.CCMask);
3965}
3966
3967SDValue SystemZTargetLowering::lowerSTRICT_FSETCC(SDValue Op,
3968 SelectionDAG &DAG,
3969 bool IsSignaling) const {
3970 SDValue Chain = Op.getOperand(0);
3971 SDValue CmpOp0 = Op.getOperand(1);
3972 SDValue CmpOp1 = Op.getOperand(2);
3973 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(3))->get();
3974 SDLoc DL(Op);
3975 EVT VT = Op.getNode()->getValueType(0);
3976 if (VT.isVector()) {
3977 SDValue Res = lowerVectorSETCC(DAG, DL, VT, CC, CmpOp0, CmpOp1,
3978 Chain, IsSignaling);
3979 return Res.getValue(Op.getResNo());
3980 }
3981
3982 Comparison C(getCmp(DAG, CmpOp0, CmpOp1, CC, DL, Chain, IsSignaling));
3983 SDValue CCReg = emitCmp(DAG, DL, C);
3984 CCReg->setFlags(Op->getFlags());
3985 SDValue Result = emitSETCC(DAG, DL, CCReg, C.CCValid, C.CCMask);
3986 SDValue Ops[2] = { Result, CCReg.getValue(1) };
3987 return DAG.getMergeValues(Ops, DL);
3988}
3989
3990SDValue SystemZTargetLowering::lowerBR_CC(SDValue Op, SelectionDAG &DAG) const {
3991 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
3992 SDValue CmpOp0 = Op.getOperand(2);
3993 SDValue CmpOp1 = Op.getOperand(3);
3994 SDValue Dest = Op.getOperand(4);
3995 SDLoc DL(Op);
3996
3997 Comparison C(getCmp(DAG, CmpOp0, CmpOp1, CC, DL));
3998 SDValue CCReg = emitCmp(DAG, DL, C);
3999 return DAG.getNode(
4000 SystemZISD::BR_CCMASK, DL, Op.getValueType(), Op.getOperand(0),
4001 DAG.getTargetConstant(C.CCValid, DL, MVT::i32),
4002 DAG.getTargetConstant(C.CCMask, DL, MVT::i32), Dest, CCReg);
4003}
4004
4005// Return true if Pos is CmpOp and Neg is the negative of CmpOp,
4006// allowing Pos and Neg to be wider than CmpOp.
4007static bool isAbsolute(SDValue CmpOp, SDValue Pos, SDValue Neg) {
4008 return (Neg.getOpcode() == ISD::SUB &&
4009 Neg.getOperand(0).getOpcode() == ISD::Constant &&
4010 Neg.getConstantOperandVal(0) == 0 && Neg.getOperand(1) == Pos &&
4011 (Pos == CmpOp || (Pos.getOpcode() == ISD::SIGN_EXTEND &&
4012 Pos.getOperand(0) == CmpOp)));
4013}
4014
4015// Return the absolute or negative absolute of Op; IsNegative decides which.
4017 bool IsNegative) {
4018 Op = DAG.getNode(ISD::ABS, DL, Op.getValueType(), Op);
4019 if (IsNegative)
4020 Op = DAG.getNode(ISD::SUB, DL, Op.getValueType(),
4021 DAG.getConstant(0, DL, Op.getValueType()), Op);
4022 return Op;
4023}
4024
4026 Comparison C, SDValue TrueOp, SDValue FalseOp) {
4027 EVT VT = MVT::i128;
4028 unsigned Op;
4029
4030 if (C.CCMask == SystemZ::CCMASK_CMP_NE ||
4031 C.CCMask == SystemZ::CCMASK_CMP_GE ||
4032 C.CCMask == SystemZ::CCMASK_CMP_LE) {
4033 std::swap(TrueOp, FalseOp);
4034 C.CCMask ^= C.CCValid;
4035 }
4036 if (C.CCMask == SystemZ::CCMASK_CMP_LT) {
4037 std::swap(C.Op0, C.Op1);
4038 C.CCMask = SystemZ::CCMASK_CMP_GT;
4039 }
4040 switch (C.CCMask) {
4042 Op = SystemZISD::VICMPE;
4043 break;
4045 if (C.ICmpType == SystemZICMP::UnsignedOnly)
4046 Op = SystemZISD::VICMPHL;
4047 else
4048 Op = SystemZISD::VICMPH;
4049 break;
4050 default:
4051 llvm_unreachable("Unhandled comparison");
4052 break;
4053 }
4054
4055 SDValue Mask = DAG.getNode(Op, DL, VT, C.Op0, C.Op1);
4056 TrueOp = DAG.getNode(ISD::AND, DL, VT, TrueOp, Mask);
4057 FalseOp = DAG.getNode(ISD::AND, DL, VT, FalseOp, DAG.getNOT(DL, Mask, VT));
4058 return DAG.getNode(ISD::OR, DL, VT, TrueOp, FalseOp);
4059}
4060
4061SDValue SystemZTargetLowering::lowerSELECT_CC(SDValue Op,
4062 SelectionDAG &DAG) const {
4063 SDValue CmpOp0 = Op.getOperand(0);
4064 SDValue CmpOp1 = Op.getOperand(1);
4065 SDValue TrueOp = Op.getOperand(2);
4066 SDValue FalseOp = Op.getOperand(3);
4067 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
4068 SDLoc DL(Op);
4069
4070 // SELECT_CC involving f16 will not have the cmp-ops promoted by the
4071 // legalizer, as it will be handled according to the type of the resulting
4072 // value. Extend them here if needed.
4073 if (CmpOp0.getSimpleValueType() == MVT::f16) {
4074 CmpOp0 = DAG.getFPExtendOrRound(CmpOp0, SDLoc(CmpOp0), MVT::f32);
4075 CmpOp1 = DAG.getFPExtendOrRound(CmpOp1, SDLoc(CmpOp1), MVT::f32);
4076 }
4077
4078 Comparison C(getCmp(DAG, CmpOp0, CmpOp1, CC, DL));
4079
4080 // Check for absolute and negative-absolute selections, including those
4081 // where the comparison value is sign-extended (for LPGFR and LNGFR).
4082 // This check supplements the one in DAGCombiner.
4083 if (C.Opcode == SystemZISD::ICMP && C.CCMask != SystemZ::CCMASK_CMP_EQ &&
4084 C.CCMask != SystemZ::CCMASK_CMP_NE &&
4085 C.Op1.getOpcode() == ISD::Constant &&
4086 cast<ConstantSDNode>(C.Op1)->getValueSizeInBits(0) <= 64 &&
4087 C.Op1->getAsZExtVal() == 0) {
4088 if (isAbsolute(C.Op0, TrueOp, FalseOp))
4089 return getAbsolute(DAG, DL, TrueOp, C.CCMask & SystemZ::CCMASK_CMP_LT);
4090 if (isAbsolute(C.Op0, FalseOp, TrueOp))
4091 return getAbsolute(DAG, DL, FalseOp, C.CCMask & SystemZ::CCMASK_CMP_GT);
4092 }
4093
4094 if (Subtarget.hasVectorEnhancements3() &&
4095 C.Opcode == SystemZISD::ICMP &&
4096 C.Op0.getValueType() == MVT::i128 &&
4097 TrueOp.getValueType() == MVT::i128) {
4098 return getI128Select(DAG, DL, C, TrueOp, FalseOp);
4099 }
4100
4101 SDValue CCReg = emitCmp(DAG, DL, C);
4102 SDValue Ops[] = {TrueOp, FalseOp,
4103 DAG.getTargetConstant(C.CCValid, DL, MVT::i32),
4104 DAG.getTargetConstant(C.CCMask, DL, MVT::i32), CCReg};
4105
4106 return DAG.getNode(SystemZISD::SELECT_CCMASK, DL, Op.getValueType(), Ops);
4107}
4108
4109SDValue SystemZTargetLowering::lowerGlobalAddress(GlobalAddressSDNode *Node,
4110 SelectionDAG &DAG) const {
4111 SDLoc DL(Node);
4112 const GlobalValue *GV = Node->getGlobal();
4113 int64_t Offset = Node->getOffset();
4114 EVT PtrVT = getPointerTy(DAG.getDataLayout());
4116
4118 if (Subtarget.isPC32DBLSymbol(GV, CM)) {
4119 if (isInt<32>(Offset)) {
4120 // Assign anchors at 1<<12 byte boundaries.
4121 uint64_t Anchor = Offset & ~uint64_t(0xfff);
4122 Result = DAG.getTargetGlobalAddress(GV, DL, PtrVT, Anchor);
4123 Result = DAG.getNode(SystemZISD::PCREL_WRAPPER, DL, PtrVT, Result);
4124
4125 // The offset can be folded into the address if it is aligned to a
4126 // halfword.
4127 Offset -= Anchor;
4128 if (Offset != 0 && (Offset & 1) == 0) {
4129 SDValue Full =
4130 DAG.getTargetGlobalAddress(GV, DL, PtrVT, Anchor + Offset);
4131 Result = DAG.getNode(SystemZISD::PCREL_OFFSET, DL, PtrVT, Full, Result);
4132 Offset = 0;
4133 }
4134 } else {
4135 // Conservatively load a constant offset greater than 32 bits into a
4136 // register below.
4137 Result = DAG.getTargetGlobalAddress(GV, DL, PtrVT);
4138 Result = DAG.getNode(SystemZISD::PCREL_WRAPPER, DL, PtrVT, Result);
4139 }
4140 } else if (Subtarget.isTargetELF()) {
4141 Result = DAG.getTargetGlobalAddress(GV, DL, PtrVT, 0, SystemZII::MO_GOT);
4142 Result = DAG.getNode(SystemZISD::PCREL_WRAPPER, DL, PtrVT, Result);
4143 Result = DAG.getLoad(PtrVT, DL, DAG.getEntryNode(), Result,
4145 } else if (Subtarget.isTargetzOS()) {
4146 Result = getADAEntry(DAG, GV, DL, PtrVT);
4147 } else
4148 llvm_unreachable("Unexpected Subtarget");
4149
4150 // If there was a non-zero offset that we didn't fold, create an explicit
4151 // addition for it.
4152 if (Offset != 0)
4153 Result = DAG.getNode(ISD::ADD, DL, PtrVT, Result,
4154 DAG.getSignedConstant(Offset, DL, PtrVT));
4155
4156 return Result;
4157}
4158
4159SDValue SystemZTargetLowering::lowerTLSGetOffset(GlobalAddressSDNode *Node,
4160 SelectionDAG &DAG,
4161 unsigned Opcode,
4162 SDValue GOTOffset) const {
4163 SDLoc DL(Node);
4164 EVT PtrVT = getPointerTy(DAG.getDataLayout());
4165 SDValue Chain = DAG.getEntryNode();
4166 SDValue Glue;
4167
4170 report_fatal_error("In GHC calling convention TLS is not supported");
4171
4172 // __tls_get_offset takes the GOT offset in %r2 and the GOT in %r12.
4173 SDValue GOT = DAG.getGLOBAL_OFFSET_TABLE(PtrVT);
4174 Chain = DAG.getCopyToReg(Chain, DL, SystemZ::R12D, GOT, Glue);
4175 Glue = Chain.getValue(1);
4176 Chain = DAG.getCopyToReg(Chain, DL, SystemZ::R2D, GOTOffset, Glue);
4177 Glue = Chain.getValue(1);
4178
4179 // The first call operand is the chain and the second is the TLS symbol.
4181 Ops.push_back(Chain);
4182 Ops.push_back(DAG.getTargetGlobalAddress(Node->getGlobal(), DL,
4183 Node->getValueType(0),
4184 0, 0));
4185
4186 // Add argument registers to the end of the list so that they are
4187 // known live into the call.
4188 Ops.push_back(DAG.getRegister(SystemZ::R2D, PtrVT));
4189 Ops.push_back(DAG.getRegister(SystemZ::R12D, PtrVT));
4190
4191 // Add a register mask operand representing the call-preserved registers.
4192 const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();
4193 const uint32_t *Mask =
4194 TRI->getCallPreservedMask(DAG.getMachineFunction(), CallingConv::C);
4195 assert(Mask && "Missing call preserved mask for calling convention");
4196 Ops.push_back(DAG.getRegisterMask(Mask));
4197
4198 // Glue the call to the argument copies.
4199 Ops.push_back(Glue);
4200
4201 // Emit the call.
4202 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
4203 Chain = DAG.getNode(Opcode, DL, NodeTys, Ops);
4204 Glue = Chain.getValue(1);
4205
4206 // Copy the return value from %r2.
4207 return DAG.getCopyFromReg(Chain, DL, SystemZ::R2D, PtrVT, Glue);
4208}
4209
4210SDValue SystemZTargetLowering::lowerThreadPointer(const SDLoc &DL,
4211 SelectionDAG &DAG) const {
4212 SDValue Chain = DAG.getEntryNode();
4213 EVT PtrVT = getPointerTy(DAG.getDataLayout());
4214
4215 // The high part of the thread pointer is in access register 0.
4216 SDValue TPHi = DAG.getCopyFromReg(Chain, DL, SystemZ::A0, MVT::i32);
4217 TPHi = DAG.getNode(ISD::ANY_EXTEND, DL, PtrVT, TPHi);
4218
4219 // The low part of the thread pointer is in access register 1.
4220 SDValue TPLo = DAG.getCopyFromReg(Chain, DL, SystemZ::A1, MVT::i32);
4221 TPLo = DAG.getNode(ISD::ZERO_EXTEND, DL, PtrVT, TPLo);
4222
4223 // Merge them into a single 64-bit address.
4224 SDValue TPHiShifted = DAG.getNode(ISD::SHL, DL, PtrVT, TPHi,
4225 DAG.getConstant(32, DL, PtrVT));
4226 return DAG.getNode(ISD::OR, DL, PtrVT, TPHiShifted, TPLo);
4227}
4228
4229SDValue SystemZTargetLowering::lowerGlobalTLSAddress(GlobalAddressSDNode *Node,
4230 SelectionDAG &DAG) const {
4231 if (DAG.getTarget().useEmulatedTLS())
4232 return LowerToTLSEmulatedModel(Node, DAG);
4233 SDLoc DL(Node);
4234 const GlobalValue *GV = Node->getGlobal();
4235 EVT PtrVT = getPointerTy(DAG.getDataLayout());
4236 TLSModel::Model model = DAG.getTarget().getTLSModel(GV);
4237
4240 report_fatal_error("In GHC calling convention TLS is not supported");
4241
4242 SDValue TP = lowerThreadPointer(DL, DAG);
4243
4244 // Get the offset of GA from the thread pointer, based on the TLS model.
4246 switch (model) {
4248 // Load the GOT offset of the tls_index (module ID / per-symbol offset).
4249 SystemZConstantPoolValue *CPV =
4251
4252 Offset = DAG.getConstantPool(CPV, PtrVT, Align(8));
4253 Offset = DAG.getLoad(
4254 PtrVT, DL, DAG.getEntryNode(), Offset,
4256
4257 // Call __tls_get_offset to retrieve the offset.
4258 Offset = lowerTLSGetOffset(Node, DAG, SystemZISD::TLS_GDCALL, Offset);
4259 break;
4260 }
4261
4263 // Load the GOT offset of the module ID.
4264 SystemZConstantPoolValue *CPV =
4266
4267 Offset = DAG.getConstantPool(CPV, PtrVT, Align(8));
4268 Offset = DAG.getLoad(
4269 PtrVT, DL, DAG.getEntryNode(), Offset,
4271
4272 // Call __tls_get_offset to retrieve the module base offset.
4273 Offset = lowerTLSGetOffset(Node, DAG, SystemZISD::TLS_LDCALL, Offset);
4274
4275 // Note: The SystemZLDCleanupPass will remove redundant computations
4276 // of the module base offset. Count total number of local-dynamic
4277 // accesses to trigger execution of that pass.
4278 SystemZMachineFunctionInfo* MFI =
4279 DAG.getMachineFunction().getInfo<SystemZMachineFunctionInfo>();
4281
4282 // Add the per-symbol offset.
4284
4285 SDValue DTPOffset = DAG.getConstantPool(CPV, PtrVT, Align(8));
4286 DTPOffset = DAG.getLoad(
4287 PtrVT, DL, DAG.getEntryNode(), DTPOffset,
4289
4290 Offset = DAG.getNode(ISD::ADD, DL, PtrVT, Offset, DTPOffset);
4291 break;
4292 }
4293
4294 case TLSModel::InitialExec: {
4295 // Load the offset from the GOT.
4296 Offset = DAG.getTargetGlobalAddress(GV, DL, PtrVT, 0,
4298 Offset = DAG.getNode(SystemZISD::PCREL_WRAPPER, DL, PtrVT, Offset);
4299 Offset =
4300 DAG.getLoad(PtrVT, DL, DAG.getEntryNode(), Offset,
4302 break;
4303 }
4304
4305 case TLSModel::LocalExec: {
4306 // Force the offset into the constant pool and load it from there.
4307 SystemZConstantPoolValue *CPV =
4309
4310 Offset = DAG.getConstantPool(CPV, PtrVT, Align(8));
4311 Offset = DAG.getLoad(
4312 PtrVT, DL, DAG.getEntryNode(), Offset,
4314 break;
4315 }
4316 }
4317
4318 // Add the base and offset together.
4319 return DAG.getNode(ISD::ADD, DL, PtrVT, TP, Offset);
4320}
4321
4322SDValue SystemZTargetLowering::lowerBlockAddress(BlockAddressSDNode *Node,
4323 SelectionDAG &DAG) const {
4324 SDLoc DL(Node);
4325 const BlockAddress *BA = Node->getBlockAddress();
4326 int64_t Offset = Node->getOffset();
4327 EVT PtrVT = getPointerTy(DAG.getDataLayout());
4328
4329 SDValue Result = DAG.getTargetBlockAddress(BA, PtrVT, Offset);
4330 Result = DAG.getNode(SystemZISD::PCREL_WRAPPER, DL, PtrVT, Result);
4331 return Result;
4332}
4333
4334SDValue SystemZTargetLowering::lowerJumpTable(JumpTableSDNode *JT,
4335 SelectionDAG &DAG) const {
4336 SDLoc DL(JT);
4337 EVT PtrVT = getPointerTy(DAG.getDataLayout());
4338 SDValue Result = DAG.getTargetJumpTable(JT->getIndex(), PtrVT);
4339
4340 // Use LARL to load the address of the table.
4341 return DAG.getNode(SystemZISD::PCREL_WRAPPER, DL, PtrVT, Result);
4342}
4343
4344SDValue SystemZTargetLowering::lowerConstantPool(ConstantPoolSDNode *CP,
4345 SelectionDAG &DAG) const {
4346 SDLoc DL(CP);
4347 EVT PtrVT = getPointerTy(DAG.getDataLayout());
4348
4351 Result =
4352 DAG.getTargetConstantPool(CP->getMachineCPVal(), PtrVT, CP->getAlign());
4353 else
4354 Result = DAG.getTargetConstantPool(CP->getConstVal(), PtrVT, CP->getAlign(),
4355 CP->getOffset());
4356
4357 // Use LARL to load the address of the constant pool entry.
4358 return DAG.getNode(SystemZISD::PCREL_WRAPPER, DL, PtrVT, Result);
4359}
4360
4361SDValue SystemZTargetLowering::lowerFRAMEADDR(SDValue Op,
4362 SelectionDAG &DAG) const {
4363 auto *TFL = Subtarget.getFrameLowering<SystemZFrameLowering>();
4365 MachineFrameInfo &MFI = MF.getFrameInfo();
4366 MFI.setFrameAddressIsTaken(true);
4367
4368 SDLoc DL(Op);
4369 unsigned Depth = Op.getConstantOperandVal(0);
4370 EVT PtrVT = getPointerTy(DAG.getDataLayout());
4371
4372 // By definition, the frame address is the address of the back chain. (In
4373 // the case of packed stack without backchain, return the address where the
4374 // backchain would have been stored. This will either be an unused space or
4375 // contain a saved register).
4376 int BackChainIdx = TFL->getOrCreateFramePointerSaveIndex(MF);
4377 SDValue BackChain = DAG.getFrameIndex(BackChainIdx, PtrVT);
4378
4379 if (Depth > 0) {
4380 // FIXME The frontend should detect this case.
4381 if (!MF.getSubtarget<SystemZSubtarget>().hasBackChain())
4382 report_fatal_error("Unsupported stack frame traversal count");
4383
4384 SDValue Offset = DAG.getConstant(TFL->getBackchainOffset(MF), DL, PtrVT);
4385 while (Depth--) {
4386 BackChain = DAG.getLoad(PtrVT, DL, DAG.getEntryNode(), BackChain,
4387 MachinePointerInfo());
4388 BackChain = DAG.getNode(ISD::ADD, DL, PtrVT, BackChain, Offset);
4389 }
4390 }
4391
4392 return BackChain;
4393}
4394
4395SDValue SystemZTargetLowering::lowerRETURNADDR(SDValue Op,
4396 SelectionDAG &DAG) const {
4398 MachineFrameInfo &MFI = MF.getFrameInfo();
4399 MFI.setReturnAddressIsTaken(true);
4400
4401 SDLoc DL(Op);
4402 unsigned Depth = Op.getConstantOperandVal(0);
4403 EVT PtrVT = getPointerTy(DAG.getDataLayout());
4404
4405 if (Depth > 0) {
4406 // FIXME The frontend should detect this case.
4407 if (!MF.getSubtarget<SystemZSubtarget>().hasBackChain())
4408 report_fatal_error("Unsupported stack frame traversal count");
4409
4410 SDValue FrameAddr = lowerFRAMEADDR(Op, DAG);
4411 const auto *TFL = Subtarget.getFrameLowering<SystemZFrameLowering>();
4412 int Offset = TFL->getReturnAddressOffset(MF);
4413 SDValue Ptr = DAG.getNode(ISD::ADD, DL, PtrVT, FrameAddr,
4414 DAG.getSignedConstant(Offset, DL, PtrVT));
4415 return DAG.getLoad(PtrVT, DL, DAG.getEntryNode(), Ptr,
4416 MachinePointerInfo());
4417 }
4418
4419 // Return R14D (Elf) / R7D (XPLINK), which has the return address. Mark it an
4420 // implicit live-in.
4421 SystemZCallingConventionRegisters *CCR = Subtarget.getSpecialRegisters();
4423 &SystemZ::GR64BitRegClass);
4424 return DAG.getCopyFromReg(DAG.getEntryNode(), DL, LinkReg, PtrVT);
4425}
4426
4427SDValue SystemZTargetLowering::lowerBITCAST(SDValue Op,
4428 SelectionDAG &DAG) const {
4429 SDLoc DL(Op);
4430 SDValue In = Op.getOperand(0);
4431 EVT InVT = In.getValueType();
4432 EVT ResVT = Op.getValueType();
4433
4434 // Convert loads directly. This is normally done by DAGCombiner,
4435 // but we need this case for bitcasts that are created during lowering
4436 // and which are then lowered themselves.
4437 if (auto *LoadN = dyn_cast<LoadSDNode>(In))
4438 if (ISD::isNormalLoad(LoadN)) {
4439 SDValue NewLoad = DAG.getLoad(ResVT, DL, LoadN->getChain(),
4440 LoadN->getBasePtr(), LoadN->getMemOperand());
4441 // Update the chain uses.
4442 DAG.ReplaceAllUsesOfValueWith(SDValue(LoadN, 1), NewLoad.getValue(1));
4443 return NewLoad;
4444 }
4445
4446 if (InVT == MVT::i32 && ResVT == MVT::f32) {
4447 SDValue In64;
4448 if (Subtarget.hasHighWord()) {
4449 SDNode *U64 = DAG.getMachineNode(TargetOpcode::IMPLICIT_DEF, DL,
4450 MVT::i64);
4451 In64 = DAG.getTargetInsertSubreg(SystemZ::subreg_h32, DL,
4452 MVT::i64, SDValue(U64, 0), In);
4453 } else {
4454 In64 = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, In);
4455 In64 = DAG.getNode(ISD::SHL, DL, MVT::i64, In64,
4456 DAG.getConstant(32, DL, MVT::i64));
4457 }
4458 SDValue Out64 = DAG.getNode(ISD::BITCAST, DL, MVT::f64, In64);
4459 return DAG.getTargetExtractSubreg(SystemZ::subreg_h32,
4460 DL, MVT::f32, Out64);
4461 }
4462 if (InVT == MVT::f32 && ResVT == MVT::i32) {
4463 SDNode *U64 = DAG.getMachineNode(TargetOpcode::IMPLICIT_DEF, DL, MVT::f64);
4464 SDValue In64 = DAG.getTargetInsertSubreg(SystemZ::subreg_h32, DL,
4465 MVT::f64, SDValue(U64, 0), In);
4466 SDValue Out64 = DAG.getNode(ISD::BITCAST, DL, MVT::i64, In64);
4467 if (Subtarget.hasHighWord())
4468 return DAG.getTargetExtractSubreg(SystemZ::subreg_h32, DL,
4469 MVT::i32, Out64);
4470 SDValue Shift = DAG.getNode(ISD::SRL, DL, MVT::i64, Out64,
4471 DAG.getConstant(32, DL, MVT::i64));
4472 return DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Shift);
4473 }
4474 llvm_unreachable("Unexpected bitcast combination");
4475}
4476
4477SDValue SystemZTargetLowering::lowerVASTART(SDValue Op,
4478 SelectionDAG &DAG) const {
4479
4480 if (Subtarget.isTargetXPLINK64())
4481 return lowerVASTART_XPLINK(Op, DAG);
4482 else
4483 return lowerVASTART_ELF(Op, DAG);
4484}
4485
4486SDValue SystemZTargetLowering::lowerVASTART_XPLINK(SDValue Op,
4487 SelectionDAG &DAG) const {
4489 SystemZMachineFunctionInfo *FuncInfo =
4490 MF.getInfo<SystemZMachineFunctionInfo>();
4491
4492 SDLoc DL(Op);
4493
4494 // vastart just stores the address of the VarArgsFrameIndex slot into the
4495 // memory location argument.
4496 EVT PtrVT = getPointerTy(DAG.getDataLayout());
4497 SDValue FR = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(), PtrVT);
4498 const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
4499 return DAG.getStore(Op.getOperand(0), DL, FR, Op.getOperand(1),
4500 MachinePointerInfo(SV));
4501}
4502
4503SDValue SystemZTargetLowering::lowerVASTART_ELF(SDValue Op,
4504 SelectionDAG &DAG) const {
4506 SystemZMachineFunctionInfo *FuncInfo =
4507 MF.getInfo<SystemZMachineFunctionInfo>();
4508 EVT PtrVT = getPointerTy(DAG.getDataLayout());
4509
4510 SDValue Chain = Op.getOperand(0);
4511 SDValue Addr = Op.getOperand(1);
4512 const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
4513 SDLoc DL(Op);
4514
4515 // The initial values of each field.
4516 const unsigned NumFields = 4;
4517 SDValue Fields[NumFields] = {
4518 DAG.getConstant(FuncInfo->getVarArgsFirstGPR(), DL, PtrVT),
4519 DAG.getConstant(FuncInfo->getVarArgsFirstFPR(), DL, PtrVT),
4520 DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(), PtrVT),
4521 DAG.getFrameIndex(FuncInfo->getRegSaveFrameIndex(), PtrVT)
4522 };
4523
4524 // Store each field into its respective slot.
4525 SDValue MemOps[NumFields];
4526 unsigned Offset = 0;
4527 for (unsigned I = 0; I < NumFields; ++I) {
4528 SDValue FieldAddr = Addr;
4529 if (Offset != 0)
4530 FieldAddr = DAG.getNode(ISD::ADD, DL, PtrVT, FieldAddr,
4532 MemOps[I] = DAG.getStore(Chain, DL, Fields[I], FieldAddr,
4533 MachinePointerInfo(SV, Offset));
4534 Offset += 8;
4535 }
4536 return DAG.getNode(ISD::TokenFactor, DL, MVT::Other, MemOps);
4537}
4538
4539SDValue SystemZTargetLowering::lowerVACOPY(SDValue Op,
4540 SelectionDAG &DAG) const {
4541 SDValue Chain = Op.getOperand(0);
4542 SDValue DstPtr = Op.getOperand(1);
4543 SDValue SrcPtr = Op.getOperand(2);
4544 const Value *DstSV = cast<SrcValueSDNode>(Op.getOperand(3))->getValue();
4545 const Value *SrcSV = cast<SrcValueSDNode>(Op.getOperand(4))->getValue();
4546 SDLoc DL(Op);
4547
4548 uint32_t Sz =
4549 Subtarget.isTargetXPLINK64() ? getTargetMachine().getPointerSize(0) : 32;
4550 return DAG.getMemcpy(Chain, DL, DstPtr, SrcPtr, DAG.getIntPtrConstant(Sz, DL),
4551 Align(8), Align(8), /*isVolatile*/ false,
4552 /*AlwaysInline*/ false,
4553 /*CI=*/nullptr, std::nullopt, MachinePointerInfo(DstSV),
4554 MachinePointerInfo(SrcSV));
4555}
4556
4557SDValue
4558SystemZTargetLowering::lowerDYNAMIC_STACKALLOC(SDValue Op,
4559 SelectionDAG &DAG) const {
4560 if (Subtarget.isTargetXPLINK64())
4561 return lowerDYNAMIC_STACKALLOC_XPLINK(Op, DAG);
4562 else
4563 return lowerDYNAMIC_STACKALLOC_ELF(Op, DAG);
4564}
4565
4566SDValue
4567SystemZTargetLowering::lowerDYNAMIC_STACKALLOC_XPLINK(SDValue Op,
4568 SelectionDAG &DAG) const {
4569 const TargetFrameLowering *TFI = Subtarget.getFrameLowering();
4571 bool RealignOpt = !MF.getFunction().hasFnAttribute("no-realign-stack");
4572 SDValue Chain = Op.getOperand(0);
4573 SDValue Size = Op.getOperand(1);
4574 SDValue Align = Op.getOperand(2);
4575 SDLoc DL(Op);
4576
4577 // If user has set the no alignment function attribute, ignore
4578 // alloca alignments.
4579 uint64_t AlignVal = (RealignOpt ? Align->getAsZExtVal() : 0);
4580
4581 uint64_t StackAlign = TFI->getStackAlignment();
4582 uint64_t RequiredAlign = std::max(AlignVal, StackAlign);
4583 uint64_t ExtraAlignSpace = RequiredAlign - StackAlign;
4584
4585 SDValue NeededSpace = Size;
4586
4587 // Add extra space for alignment if needed.
4588 EVT PtrVT = getPointerTy(MF.getDataLayout());
4589 if (ExtraAlignSpace)
4590 NeededSpace = DAG.getNode(ISD::ADD, DL, PtrVT, NeededSpace,
4591 DAG.getConstant(ExtraAlignSpace, DL, PtrVT));
4592
4593 bool IsSigned = false;
4594 bool DoesNotReturn = false;
4595 bool IsReturnValueUsed = false;
4596 EVT VT = Op.getValueType();
4597 SDValue AllocaCall =
4598 makeExternalCall(Chain, DAG, "@@ALCAXP", VT, ArrayRef(NeededSpace),
4599 CallingConv::C, IsSigned, DL, DoesNotReturn,
4600 IsReturnValueUsed)
4601 .first;
4602
4603 // Perform a CopyFromReg from %GPR4 (stack pointer register). Chain and Glue
4604 // to end of call in order to ensure it isn't broken up from the call
4605 // sequence.
4606 auto &Regs = Subtarget.getSpecialRegisters<SystemZXPLINK64Registers>();
4607 Register SPReg = Regs.getStackPointerRegister();
4608 Chain = AllocaCall.getValue(1);
4609 SDValue Glue = AllocaCall.getValue(2);
4610 SDValue NewSPRegNode = DAG.getCopyFromReg(Chain, DL, SPReg, PtrVT, Glue);
4611 Chain = NewSPRegNode.getValue(1);
4612
4613 MVT PtrMVT = getPointerMemTy(MF.getDataLayout());
4614 SDValue ArgAdjust = DAG.getNode(SystemZISD::ADJDYNALLOC, DL, PtrMVT);
4615 SDValue Result = DAG.getNode(ISD::ADD, DL, PtrMVT, NewSPRegNode, ArgAdjust);
4616
4617 // Dynamically realign if needed.
4618 if (ExtraAlignSpace) {
4619 Result = DAG.getNode(ISD::ADD, DL, PtrVT, Result,
4620 DAG.getConstant(ExtraAlignSpace, DL, PtrVT));
4621 Result = DAG.getNode(ISD::AND, DL, PtrVT, Result,
4622 DAG.getConstant(~(RequiredAlign - 1), DL, PtrVT));
4623 }
4624
4625 SDValue Ops[2] = {Result, Chain};
4626 return DAG.getMergeValues(Ops, DL);
4627}
4628
4629SDValue
4630SystemZTargetLowering::lowerDYNAMIC_STACKALLOC_ELF(SDValue Op,
4631 SelectionDAG &DAG) const {
4632 const TargetFrameLowering *TFI = Subtarget.getFrameLowering();
4634 bool RealignOpt = !MF.getFunction().hasFnAttribute("no-realign-stack");
4635 bool StoreBackchain = MF.getSubtarget<SystemZSubtarget>().hasBackChain();
4636
4637 SDValue Chain = Op.getOperand(0);
4638 SDValue Size = Op.getOperand(1);
4639 SDValue Align = Op.getOperand(2);
4640 SDLoc DL(Op);
4641
4642 // If user has set the no alignment function attribute, ignore
4643 // alloca alignments.
4644 uint64_t AlignVal = (RealignOpt ? Align->getAsZExtVal() : 0);
4645
4646 uint64_t StackAlign = TFI->getStackAlignment();
4647 uint64_t RequiredAlign = std::max(AlignVal, StackAlign);
4648 uint64_t ExtraAlignSpace = RequiredAlign - StackAlign;
4649
4651 SDValue NeededSpace = Size;
4652
4653 // Get a reference to the stack pointer.
4654 SDValue OldSP = DAG.getCopyFromReg(Chain, DL, SPReg, MVT::i64);
4655
4656 // If we need a backchain, save it now.
4657 SDValue Backchain;
4658 if (StoreBackchain)
4659 Backchain = DAG.getLoad(MVT::i64, DL, Chain, getBackchainAddress(OldSP, DAG),
4660 MachinePointerInfo());
4661
4662 // Add extra space for alignment if needed.
4663 if (ExtraAlignSpace)
4664 NeededSpace = DAG.getNode(ISD::ADD, DL, MVT::i64, NeededSpace,
4665 DAG.getConstant(ExtraAlignSpace, DL, MVT::i64));
4666
4667 // Get the new stack pointer value.
4668 SDValue NewSP;
4669 if (hasInlineStackProbe(MF)) {
4670 NewSP = DAG.getNode(SystemZISD::PROBED_ALLOCA, DL,
4671 DAG.getVTList(MVT::i64, MVT::Other), Chain, OldSP, NeededSpace);
4672 Chain = NewSP.getValue(1);
4673 }
4674 else {
4675 NewSP = DAG.getNode(ISD::SUB, DL, MVT::i64, OldSP, NeededSpace);
4676 // Copy the new stack pointer back.
4677 Chain = DAG.getCopyToReg(Chain, DL, SPReg, NewSP);
4678 }
4679
4680 // The allocated data lives above the 160 bytes allocated for the standard
4681 // frame, plus any outgoing stack arguments. We don't know how much that
4682 // amounts to yet, so emit a special ADJDYNALLOC placeholder.
4683 SDValue ArgAdjust = DAG.getNode(SystemZISD::ADJDYNALLOC, DL, MVT::i64);
4684 SDValue Result = DAG.getNode(ISD::ADD, DL, MVT::i64, NewSP, ArgAdjust);
4685
4686 // Dynamically realign if needed.
4687 if (RequiredAlign > StackAlign) {
4688 Result =
4689 DAG.getNode(ISD::ADD, DL, MVT::i64, Result,
4690 DAG.getConstant(ExtraAlignSpace, DL, MVT::i64));
4691 Result =
4692 DAG.getNode(ISD::AND, DL, MVT::i64, Result,
4693 DAG.getConstant(~(RequiredAlign - 1), DL, MVT::i64));
4694 }
4695
4696 if (StoreBackchain)
4697 Chain = DAG.getStore(Chain, DL, Backchain, getBackchainAddress(NewSP, DAG),
4698 MachinePointerInfo());
4699
4700 SDValue Ops[2] = { Result, Chain };
4701 return DAG.getMergeValues(Ops, DL);
4702}
4703
4704SDValue SystemZTargetLowering::lowerGET_DYNAMIC_AREA_OFFSET(
4705 SDValue Op, SelectionDAG &DAG) const {
4706 SDLoc DL(Op);
4707
4708 return DAG.getNode(SystemZISD::ADJDYNALLOC, DL, MVT::i64);
4709}
4710
4711SDValue SystemZTargetLowering::lowerMULH(SDValue Op,
4712 SelectionDAG &DAG,
4713 unsigned Opcode) const {
4714 EVT VT = Op.getValueType();
4715 SDLoc DL(Op);
4716 SDValue Even, Odd;
4717
4718 // This custom expander is only used on z17 and later for 64-bit types.
4719 assert(!is32Bit(VT));
4720 assert(Subtarget.hasMiscellaneousExtensions2());
4721
4722 // SystemZISD::xMUL_LOHI returns the low result in the odd register and
4723 // the high result in the even register. Return the latter.
4724 lowerGR128Binary(DAG, DL, VT, Opcode,
4725 Op.getOperand(0), Op.getOperand(1), Even, Odd);
4726 return Even;
4727}
4728
4729SDValue SystemZTargetLowering::lowerSMUL_LOHI(SDValue Op,
4730 SelectionDAG &DAG) const {
4731 EVT VT = Op.getValueType();
4732 SDLoc DL(Op);
4733 SDValue Ops[2];
4734 if (is32Bit(VT))
4735 // Just do a normal 64-bit multiplication and extract the results.
4736 // We define this so that it can be used for constant division.
4737 lowerMUL_LOHI32(DAG, DL, ISD::SIGN_EXTEND, Op.getOperand(0),
4738 Op.getOperand(1), Ops[1], Ops[0]);
4739 else if (Subtarget.hasMiscellaneousExtensions2())
4740 // SystemZISD::SMUL_LOHI returns the low result in the odd register and
4741 // the high result in the even register. ISD::SMUL_LOHI is defined to
4742 // return the low half first, so the results are in reverse order.
4743 lowerGR128Binary(DAG, DL, VT, SystemZISD::SMUL_LOHI,
4744 Op.getOperand(0), Op.getOperand(1), Ops[1], Ops[0]);
4745 else {
4746 // Do a full 128-bit multiplication based on SystemZISD::UMUL_LOHI:
4747 //
4748 // (ll * rl) + ((lh * rl) << 64) + ((ll * rh) << 64)
4749 //
4750 // but using the fact that the upper halves are either all zeros
4751 // or all ones:
4752 //
4753 // (ll * rl) - ((lh & rl) << 64) - ((ll & rh) << 64)
4754 //
4755 // and grouping the right terms together since they are quicker than the
4756 // multiplication:
4757 //
4758 // (ll * rl) - (((lh & rl) + (ll & rh)) << 64)
4759 SDValue C63 = DAG.getConstant(63, DL, MVT::i64);
4760 SDValue LL = Op.getOperand(0);
4761 SDValue RL = Op.getOperand(1);
4762 SDValue LH = DAG.getNode(ISD::SRA, DL, VT, LL, C63);
4763 SDValue RH = DAG.getNode(ISD::SRA, DL, VT, RL, C63);
4764 // SystemZISD::UMUL_LOHI returns the low result in the odd register and
4765 // the high result in the even register. ISD::SMUL_LOHI is defined to
4766 // return the low half first, so the results are in reverse order.
4767 lowerGR128Binary(DAG, DL, VT, SystemZISD::UMUL_LOHI,
4768 LL, RL, Ops[1], Ops[0]);
4769 SDValue NegLLTimesRH = DAG.getNode(ISD::AND, DL, VT, LL, RH);
4770 SDValue NegLHTimesRL = DAG.getNode(ISD::AND, DL, VT, LH, RL);
4771 SDValue NegSum = DAG.getNode(ISD::ADD, DL, VT, NegLLTimesRH, NegLHTimesRL);
4772 Ops[1] = DAG.getNode(ISD::SUB, DL, VT, Ops[1], NegSum);
4773 }
4774 return DAG.getMergeValues(Ops, DL);
4775}
4776
4777SDValue SystemZTargetLowering::lowerUMUL_LOHI(SDValue Op,
4778 SelectionDAG &DAG) const {
4779 EVT VT = Op.getValueType();
4780 SDLoc DL(Op);
4781 SDValue Ops[2];
4782 if (is32Bit(VT))
4783 // Just do a normal 64-bit multiplication and extract the results.
4784 // We define this so that it can be used for constant division.
4785 lowerMUL_LOHI32(DAG, DL, ISD::ZERO_EXTEND, Op.getOperand(0),
4786 Op.getOperand(1), Ops[1], Ops[0]);
4787 else
4788 // SystemZISD::UMUL_LOHI returns the low result in the odd register and
4789 // the high result in the even register. ISD::UMUL_LOHI is defined to
4790 // return the low half first, so the results are in reverse order.
4791 lowerGR128Binary(DAG, DL, VT, SystemZISD::UMUL_LOHI,
4792 Op.getOperand(0), Op.getOperand(1), Ops[1], Ops[0]);
4793 return DAG.getMergeValues(Ops, DL);
4794}
4795
4796SDValue SystemZTargetLowering::lowerSDIVREM(SDValue Op,
4797 SelectionDAG &DAG) const {
4798 SDValue Op0 = Op.getOperand(0);
4799 SDValue Op1 = Op.getOperand(1);
4800 EVT VT = Op.getValueType();
4801 SDLoc DL(Op);
4802
4803 // We use DSGF for 32-bit division. This means the first operand must
4804 // always be 64-bit, and the second operand should be 32-bit whenever
4805 // that is possible, to improve performance.
4806 if (is32Bit(VT))
4807 Op0 = DAG.getNode(ISD::SIGN_EXTEND, DL, MVT::i64, Op0);
4808 else if (DAG.ComputeNumSignBits(Op1) > 32)
4809 Op1 = DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Op1);
4810
4811 // DSG(F) returns the remainder in the even register and the
4812 // quotient in the odd register.
4813 SDValue Ops[2];
4814 lowerGR128Binary(DAG, DL, VT, SystemZISD::SDIVREM, Op0, Op1, Ops[1], Ops[0]);
4815 return DAG.getMergeValues(Ops, DL);
4816}
4817
4818SDValue SystemZTargetLowering::lowerUDIVREM(SDValue Op,
4819 SelectionDAG &DAG) const {
4820 EVT VT = Op.getValueType();
4821 SDLoc DL(Op);
4822
4823 // DL(G) returns the remainder in the even register and the
4824 // quotient in the odd register.
4825 SDValue Ops[2];
4826 lowerGR128Binary(DAG, DL, VT, SystemZISD::UDIVREM,
4827 Op.getOperand(0), Op.getOperand(1), Ops[1], Ops[0]);
4828 return DAG.getMergeValues(Ops, DL);
4829}
4830
4831SDValue SystemZTargetLowering::lowerOR(SDValue Op, SelectionDAG &DAG) const {
4832 assert(Op.getValueType() == MVT::i64 && "Should be 64-bit operation");
4833
4834 // Get the known-zero masks for each operand.
4835 SDValue Ops[] = {Op.getOperand(0), Op.getOperand(1)};
4836 KnownBits Known[2] = {DAG.computeKnownBits(Ops[0]),
4837 DAG.computeKnownBits(Ops[1])};
4838
4839 // See if the upper 32 bits of one operand and the lower 32 bits of the
4840 // other are known zero. They are the low and high operands respectively.
4841 uint64_t Masks[] = { Known[0].Zero.getZExtValue(),
4842 Known[1].Zero.getZExtValue() };
4843 unsigned High, Low;
4844 if ((Masks[0] >> 32) == 0xffffffff && uint32_t(Masks[1]) == 0xffffffff)
4845 High = 1, Low = 0;
4846 else if ((Masks[1] >> 32) == 0xffffffff && uint32_t(Masks[0]) == 0xffffffff)
4847 High = 0, Low = 1;
4848 else
4849 return Op;
4850
4851 SDValue LowOp = Ops[Low];
4852 SDValue HighOp = Ops[High];
4853
4854 // If the high part is a constant, we're better off using IILH.
4855 if (HighOp.getOpcode() == ISD::Constant)
4856 return Op;
4857
4858 // If the low part is a constant that is outside the range of LHI,
4859 // then we're better off using IILF.
4860 if (LowOp.getOpcode() == ISD::Constant) {
4861 int64_t Value = int32_t(LowOp->getAsZExtVal());
4862 if (!isInt<16>(Value))
4863 return Op;
4864 }
4865
4866 // Check whether the high part is an AND that doesn't change the
4867 // high 32 bits and just masks out low bits. We can skip it if so.
4868 if (HighOp.getOpcode() == ISD::AND &&
4869 HighOp.getOperand(1).getOpcode() == ISD::Constant) {
4870 SDValue HighOp0 = HighOp.getOperand(0);
4872 if (DAG.MaskedValueIsZero(HighOp0, APInt(64, ~(Mask | 0xffffffff))))
4873 HighOp = HighOp0;
4874 }
4875
4876 // Take advantage of the fact that all GR32 operations only change the
4877 // low 32 bits by truncating Low to an i32 and inserting it directly
4878 // using a subreg. The interesting cases are those where the truncation
4879 // can be folded.
4880 SDLoc DL(Op);
4881 SDValue Low32 = DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, LowOp);
4882 return DAG.getTargetInsertSubreg(SystemZ::subreg_l32, DL,
4883 MVT::i64, HighOp, Low32);
4884}
4885
4886// Lower SADDO/SSUBO/UADDO/USUBO nodes.
4887SDValue SystemZTargetLowering::lowerXALUO(SDValue Op,
4888 SelectionDAG &DAG) const {
4889 SDNode *N = Op.getNode();
4890 SDValue LHS = N->getOperand(0);
4891 SDValue RHS = N->getOperand(1);
4892 SDLoc DL(N);
4893
4894 if (N->getValueType(0) == MVT::i128) {
4895 unsigned BaseOp = 0;
4896 unsigned FlagOp = 0;
4897 bool IsBorrow = false;
4898 switch (Op.getOpcode()) {
4899 default: llvm_unreachable("Unknown instruction!");
4900 case ISD::UADDO:
4901 BaseOp = ISD::ADD;
4902 FlagOp = SystemZISD::VACC;
4903 break;
4904 case ISD::USUBO:
4905 BaseOp = ISD::SUB;
4906 FlagOp = SystemZISD::VSCBI;
4907 IsBorrow = true;
4908 break;
4909 }
4910 SDValue Result = DAG.getNode(BaseOp, DL, MVT::i128, LHS, RHS);
4911 SDValue Flag = DAG.getNode(FlagOp, DL, MVT::i128, LHS, RHS);
4912 Flag = DAG.getNode(ISD::AssertZext, DL, MVT::i128, Flag,
4913 DAG.getValueType(MVT::i1));
4914 Flag = DAG.getZExtOrTrunc(Flag, DL, N->getValueType(1));
4915 if (IsBorrow)
4916 Flag = DAG.getNode(ISD::XOR, DL, Flag.getValueType(),
4917 Flag, DAG.getConstant(1, DL, Flag.getValueType()));
4918 return DAG.getNode(ISD::MERGE_VALUES, DL, N->getVTList(), Result, Flag);
4919 }
4920
4921 unsigned BaseOp = 0;
4922 unsigned CCValid = 0;
4923 unsigned CCMask = 0;
4924
4925 switch (Op.getOpcode()) {
4926 default: llvm_unreachable("Unknown instruction!");
4927 case ISD::SADDO:
4928 BaseOp = SystemZISD::SADDO;
4929 CCValid = SystemZ::CCMASK_ARITH;
4931 break;
4932 case ISD::SSUBO:
4933 BaseOp = SystemZISD::SSUBO;
4934 CCValid = SystemZ::CCMASK_ARITH;
4936 break;
4937 case ISD::UADDO:
4938 BaseOp = SystemZISD::UADDO;
4939 CCValid = SystemZ::CCMASK_LOGICAL;
4941 break;
4942 case ISD::USUBO:
4943 BaseOp = SystemZISD::USUBO;
4944 CCValid = SystemZ::CCMASK_LOGICAL;
4946 break;
4947 }
4948
4949 SDVTList VTs = DAG.getVTList(N->getValueType(0), MVT::i32);
4950 SDValue Result = DAG.getNode(BaseOp, DL, VTs, LHS, RHS);
4951
4952 SDValue SetCC = emitSETCC(DAG, DL, Result.getValue(1), CCValid, CCMask);
4953 if (N->getValueType(1) == MVT::i1)
4954 SetCC = DAG.getNode(ISD::TRUNCATE, DL, MVT::i1, SetCC);
4955
4956 return DAG.getNode(ISD::MERGE_VALUES, DL, N->getVTList(), Result, SetCC);
4957}
4958
4959static bool isAddCarryChain(SDValue Carry) {
4960 while (Carry.getOpcode() == ISD::UADDO_CARRY &&
4961 Carry->getValueType(0) != MVT::i128)
4962 Carry = Carry.getOperand(2);
4963 return Carry.getOpcode() == ISD::UADDO &&
4964 Carry->getValueType(0) != MVT::i128;
4965}
4966
4967static bool isSubBorrowChain(SDValue Carry) {
4968 while (Carry.getOpcode() == ISD::USUBO_CARRY &&
4969 Carry->getValueType(0) != MVT::i128)
4970 Carry = Carry.getOperand(2);
4971 return Carry.getOpcode() == ISD::USUBO &&
4972 Carry->getValueType(0) != MVT::i128;
4973}
4974
4975// Lower UADDO_CARRY/USUBO_CARRY nodes.
4976SDValue SystemZTargetLowering::lowerUADDSUBO_CARRY(SDValue Op,
4977 SelectionDAG &DAG) const {
4978
4979 SDNode *N = Op.getNode();
4980 MVT VT = N->getSimpleValueType(0);
4981
4982 // Let legalize expand this if it isn't a legal type yet.
4983 if (!DAG.getTargetLoweringInfo().isTypeLegal(VT))
4984 return SDValue();
4985
4986 SDValue LHS = N->getOperand(0);
4987 SDValue RHS = N->getOperand(1);
4988 SDValue Carry = Op.getOperand(2);
4989 SDLoc DL(N);
4990
4991 if (VT == MVT::i128) {
4992 unsigned BaseOp = 0;
4993 unsigned FlagOp = 0;
4994 bool IsBorrow = false;
4995 switch (Op.getOpcode()) {
4996 default: llvm_unreachable("Unknown instruction!");
4997 case ISD::UADDO_CARRY:
4998 BaseOp = SystemZISD::VAC;
4999 FlagOp = SystemZISD::VACCC;
5000 break;
5001 case ISD::USUBO_CARRY:
5002 BaseOp = SystemZISD::VSBI;
5003 FlagOp = SystemZISD::VSBCBI;
5004 IsBorrow = true;
5005 break;
5006 }
5007 if (IsBorrow)
5008 Carry = DAG.getNode(ISD::XOR, DL, Carry.getValueType(),
5009 Carry, DAG.getConstant(1, DL, Carry.getValueType()));
5010 Carry = DAG.getZExtOrTrunc(Carry, DL, MVT::i128);
5011 SDValue Result = DAG.getNode(BaseOp, DL, MVT::i128, LHS, RHS, Carry);
5012 SDValue Flag = DAG.getNode(FlagOp, DL, MVT::i128, LHS, RHS, Carry);
5013 Flag = DAG.getNode(ISD::AssertZext, DL, MVT::i128, Flag,
5014 DAG.getValueType(MVT::i1));
5015 Flag = DAG.getZExtOrTrunc(Flag, DL, N->getValueType(1));
5016 if (IsBorrow)
5017 Flag = DAG.getNode(ISD::XOR, DL, Flag.getValueType(),
5018 Flag, DAG.getConstant(1, DL, Flag.getValueType()));
5019 return DAG.getNode(ISD::MERGE_VALUES, DL, N->getVTList(), Result, Flag);
5020 }
5021
5022 unsigned BaseOp = 0;
5023 unsigned CCValid = 0;
5024 unsigned CCMask = 0;
5025
5026 switch (Op.getOpcode()) {
5027 default: llvm_unreachable("Unknown instruction!");
5028 case ISD::UADDO_CARRY:
5029 if (!isAddCarryChain(Carry))
5030 return SDValue();
5031
5032 BaseOp = SystemZISD::ADDCARRY;
5033 CCValid = SystemZ::CCMASK_LOGICAL;
5035 break;
5036 case ISD::USUBO_CARRY:
5037 if (!isSubBorrowChain(Carry))
5038 return SDValue();
5039
5040 BaseOp = SystemZISD::SUBCARRY;
5041 CCValid = SystemZ::CCMASK_LOGICAL;
5043 break;
5044 }
5045
5046 // Set the condition code from the carry flag.
5047 Carry = DAG.getNode(SystemZISD::GET_CCMASK, DL, MVT::i32, Carry,
5048 DAG.getConstant(CCValid, DL, MVT::i32),
5049 DAG.getConstant(CCMask, DL, MVT::i32));
5050
5051 SDVTList VTs = DAG.getVTList(VT, MVT::i32);
5052 SDValue Result = DAG.getNode(BaseOp, DL, VTs, LHS, RHS, Carry);
5053
5054 SDValue SetCC = emitSETCC(DAG, DL, Result.getValue(1), CCValid, CCMask);
5055 if (N->getValueType(1) == MVT::i1)
5056 SetCC = DAG.getNode(ISD::TRUNCATE, DL, MVT::i1, SetCC);
5057
5058 return DAG.getNode(ISD::MERGE_VALUES, DL, N->getVTList(), Result, SetCC);
5059}
5060
5061SDValue SystemZTargetLowering::lowerCTPOP(SDValue Op,
5062 SelectionDAG &DAG) const {
5063 EVT VT = Op.getValueType();
5064 SDLoc DL(Op);
5065 Op = Op.getOperand(0);
5066
5067 if (VT.getScalarSizeInBits() == 128) {
5068 Op = DAG.getNode(ISD::BITCAST, DL, MVT::v2i64, Op);
5069 Op = DAG.getNode(ISD::CTPOP, DL, MVT::v2i64, Op);
5070 SDValue Tmp = DAG.getSplatBuildVector(MVT::v2i64, DL,
5071 DAG.getConstant(0, DL, MVT::i64));
5072 Op = DAG.getNode(SystemZISD::VSUM, DL, VT, Op, Tmp);
5073 return Op;
5074 }
5075
5076 // Handle vector types via VPOPCT.
5077 if (VT.isVector()) {
5078 Op = DAG.getNode(ISD::BITCAST, DL, MVT::v16i8, Op);
5079 Op = DAG.getNode(SystemZISD::POPCNT, DL, MVT::v16i8, Op);
5080 switch (VT.getScalarSizeInBits()) {
5081 case 8:
5082 break;
5083 case 16: {
5084 Op = DAG.getNode(ISD::BITCAST, DL, VT, Op);
5085 SDValue Shift = DAG.getConstant(8, DL, MVT::i32);
5086 SDValue Tmp = DAG.getNode(SystemZISD::VSHL_BY_SCALAR, DL, VT, Op, Shift);
5087 Op = DAG.getNode(ISD::ADD, DL, VT, Op, Tmp);
5088 Op = DAG.getNode(SystemZISD::VSRL_BY_SCALAR, DL, VT, Op, Shift);
5089 break;
5090 }
5091 case 32: {
5092 SDValue Tmp = DAG.getSplatBuildVector(MVT::v16i8, DL,
5093 DAG.getConstant(0, DL, MVT::i32));
5094 Op = DAG.getNode(SystemZISD::VSUM, DL, VT, Op, Tmp);
5095 break;
5096 }
5097 case 64: {
5098 SDValue Tmp = DAG.getSplatBuildVector(MVT::v16i8, DL,
5099 DAG.getConstant(0, DL, MVT::i32));
5100 Op = DAG.getNode(SystemZISD::VSUM, DL, MVT::v4i32, Op, Tmp);
5101 Op = DAG.getNode(SystemZISD::VSUM, DL, VT, Op, Tmp);
5102 break;
5103 }
5104 default:
5105 llvm_unreachable("Unexpected type");
5106 }
5107 return Op;
5108 }
5109
5110 // Get the known-zero mask for the operand.
5111 KnownBits Known = DAG.computeKnownBits(Op);
5112 unsigned NumSignificantBits = Known.getMaxValue().getActiveBits();
5113 if (NumSignificantBits == 0)
5114 return DAG.getConstant(0, DL, VT);
5115
5116 // Skip known-zero high parts of the operand.
5117 int64_t OrigBitSize = VT.getSizeInBits();
5118 int64_t BitSize = llvm::bit_ceil(NumSignificantBits);
5119 BitSize = std::min(BitSize, OrigBitSize);
5120
5121 // The POPCNT instruction counts the number of bits in each byte.
5122 Op = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Op);
5123 Op = DAG.getNode(SystemZISD::POPCNT, DL, MVT::i64, Op);
5124 Op = DAG.getNode(ISD::TRUNCATE, DL, VT, Op);
5125
5126 // Add up per-byte counts in a binary tree. All bits of Op at
5127 // position larger than BitSize remain zero throughout.
5128 for (int64_t I = BitSize / 2; I >= 8; I = I / 2) {
5129 SDValue Tmp = DAG.getNode(ISD::SHL, DL, VT, Op, DAG.getConstant(I, DL, VT));
5130 if (BitSize != OrigBitSize)
5131 Tmp = DAG.getNode(ISD::AND, DL, VT, Tmp,
5132 DAG.getConstant(((uint64_t)1 << BitSize) - 1, DL, VT));
5133 Op = DAG.getNode(ISD::ADD, DL, VT, Op, Tmp);
5134 }
5135
5136 // Extract overall result from high byte.
5137 if (BitSize > 8)
5138 Op = DAG.getNode(ISD::SRL, DL, VT, Op,
5139 DAG.getConstant(BitSize - 8, DL, VT));
5140
5141 return Op;
5142}
5143
5144SDValue SystemZTargetLowering::lowerATOMIC_FENCE(SDValue Op,
5145 SelectionDAG &DAG) const {
5146 SDLoc DL(Op);
5147 AtomicOrdering FenceOrdering =
5148 static_cast<AtomicOrdering>(Op.getConstantOperandVal(1));
5149 SyncScope::ID FenceSSID =
5150 static_cast<SyncScope::ID>(Op.getConstantOperandVal(2));
5151
5152 // The only fence that needs an instruction is a sequentially-consistent
5153 // cross-thread fence.
5154 if (FenceOrdering == AtomicOrdering::SequentiallyConsistent &&
5155 FenceSSID == SyncScope::System) {
5156 return SDValue(DAG.getMachineNode(SystemZ::Serialize, DL, MVT::Other,
5157 Op.getOperand(0)),
5158 0);
5159 }
5160
5161 // MEMBARRIER is a compiler barrier; it codegens to a no-op.
5162 return DAG.getNode(ISD::MEMBARRIER, DL, MVT::Other, Op.getOperand(0));
5163}
5164
5165SDValue SystemZTargetLowering::lowerATOMIC_LOAD(SDValue Op,
5166 SelectionDAG &DAG) const {
5167 EVT RegVT = Op.getValueType();
5168 if (RegVT.getSizeInBits() == 128)
5169 return lowerATOMIC_LDST_I128(Op, DAG);
5170 return lowerLoadF16(Op, DAG);
5171}
5172
5173SDValue SystemZTargetLowering::lowerATOMIC_STORE(SDValue Op,
5174 SelectionDAG &DAG) const {
5175 auto *Node = cast<AtomicSDNode>(Op.getNode());
5176 if (Node->getMemoryVT().getSizeInBits() == 128)
5177 return lowerATOMIC_LDST_I128(Op, DAG);
5178 return lowerStoreF16(Op, DAG);
5179}
5180
5181SDValue SystemZTargetLowering::lowerATOMIC_LDST_I128(SDValue Op,
5182 SelectionDAG &DAG) const {
5183 auto *Node = cast<AtomicSDNode>(Op.getNode());
5184 assert(
5185 (Node->getMemoryVT() == MVT::i128 || Node->getMemoryVT() == MVT::f128) &&
5186 "Only custom lowering i128 or f128.");
5187 // Use same code to handle both legal and non-legal i128 types.
5189 LowerOperationWrapper(Node, Results, DAG);
5190 return DAG.getMergeValues(Results, SDLoc(Op));
5191}
5192
5193// Prepare for a Compare And Swap for a subword operation. This needs to be
5194// done in memory with 4 bytes at natural alignment.
5196 SDValue &AlignedAddr, SDValue &BitShift,
5197 SDValue &NegBitShift) {
5198 EVT PtrVT = Addr.getValueType();
5199 EVT WideVT = MVT::i32;
5200
5201 // Get the address of the containing word.
5202 AlignedAddr = DAG.getNode(ISD::AND, DL, PtrVT, Addr,
5203 DAG.getSignedConstant(-4, DL, PtrVT));
5204
5205 // Get the number of bits that the word must be rotated left in order
5206 // to bring the field to the top bits of a GR32.
5207 BitShift = DAG.getNode(ISD::SHL, DL, PtrVT, Addr,
5208 DAG.getConstant(3, DL, PtrVT));
5209 BitShift = DAG.getNode(ISD::TRUNCATE, DL, WideVT, BitShift);
5210
5211 // Get the complementing shift amount, for rotating a field in the top
5212 // bits back to its proper position.
5213 NegBitShift = DAG.getNode(ISD::SUB, DL, WideVT,
5214 DAG.getConstant(0, DL, WideVT), BitShift);
5215
5216}
5217
5218// Op is an 8-, 16-bit or 32-bit ATOMIC_LOAD_* operation. Lower the first
5219// two into the fullword ATOMIC_LOADW_* operation given by Opcode.
5220SDValue SystemZTargetLowering::lowerATOMIC_LOAD_OP(SDValue Op,
5221 SelectionDAG &DAG,
5222 unsigned Opcode) const {
5223 auto *Node = cast<AtomicSDNode>(Op.getNode());
5224
5225 // 32-bit operations need no special handling.
5226 EVT NarrowVT = Node->getMemoryVT();
5227 EVT WideVT = MVT::i32;
5228 if (NarrowVT == WideVT)
5229 return Op;
5230
5231 int64_t BitSize = NarrowVT.getSizeInBits();
5232 SDValue ChainIn = Node->getChain();
5233 SDValue Addr = Node->getBasePtr();
5234 SDValue Src2 = Node->getVal();
5235 MachineMemOperand *MMO = Node->getMemOperand();
5236 SDLoc DL(Node);
5237
5238 // Convert atomic subtracts of constants into additions.
5239 if (Opcode == SystemZISD::ATOMIC_LOADW_SUB)
5240 if (auto *Const = dyn_cast<ConstantSDNode>(Src2)) {
5241 Opcode = SystemZISD::ATOMIC_LOADW_ADD;
5242 Src2 = DAG.getSignedConstant(-Const->getSExtValue(), DL,
5243 Src2.getValueType());
5244 }
5245
5246 SDValue AlignedAddr, BitShift, NegBitShift;
5247 getCSAddressAndShifts(Addr, DAG, DL, AlignedAddr, BitShift, NegBitShift);
5248
5249 // Extend the source operand to 32 bits and prepare it for the inner loop.
5250 // ATOMIC_SWAPW uses RISBG to rotate the field left, but all other
5251 // operations require the source to be shifted in advance. (This shift
5252 // can be folded if the source is constant.) For AND and NAND, the lower
5253 // bits must be set, while for other opcodes they should be left clear.
5254 if (Opcode != SystemZISD::ATOMIC_SWAPW)
5255 Src2 = DAG.getNode(ISD::SHL, DL, WideVT, Src2,
5256 DAG.getConstant(32 - BitSize, DL, WideVT));
5257 if (Opcode == SystemZISD::ATOMIC_LOADW_AND ||
5258 Opcode == SystemZISD::ATOMIC_LOADW_NAND)
5259 Src2 = DAG.getNode(ISD::OR, DL, WideVT, Src2,
5260 DAG.getConstant(uint32_t(-1) >> BitSize, DL, WideVT));
5261
5262 // Construct the ATOMIC_LOADW_* node.
5263 SDVTList VTList = DAG.getVTList(WideVT, MVT::Other);
5264 SDValue Ops[] = { ChainIn, AlignedAddr, Src2, BitShift, NegBitShift,
5265 DAG.getConstant(BitSize, DL, WideVT) };
5266 SDValue AtomicOp = DAG.getMemIntrinsicNode(Opcode, DL, VTList, Ops,
5267 NarrowVT, MMO);
5268
5269 // Rotate the result of the final CS so that the field is in the lower
5270 // bits of a GR32, then truncate it.
5271 SDValue ResultShift = DAG.getNode(ISD::ADD, DL, WideVT, BitShift,
5272 DAG.getConstant(BitSize, DL, WideVT));
5273 SDValue Result = DAG.getNode(ISD::ROTL, DL, WideVT, AtomicOp, ResultShift);
5274
5275 SDValue RetOps[2] = { Result, AtomicOp.getValue(1) };
5276 return DAG.getMergeValues(RetOps, DL);
5277}
5278
5279// Op is an ATOMIC_LOAD_SUB operation. Lower 8- and 16-bit operations into
5280// ATOMIC_LOADW_SUBs and convert 32- and 64-bit operations into additions.
5281SDValue SystemZTargetLowering::lowerATOMIC_LOAD_SUB(SDValue Op,
5282 SelectionDAG &DAG) const {
5283 auto *Node = cast<AtomicSDNode>(Op.getNode());
5284 EVT MemVT = Node->getMemoryVT();
5285 if (MemVT == MVT::i32 || MemVT == MVT::i64) {
5286 // A full-width operation: negate and use LAA(G).
5287 assert(Op.getValueType() == MemVT && "Mismatched VTs");
5288 assert(Subtarget.hasInterlockedAccess1() &&
5289 "Should have been expanded by AtomicExpand pass.");
5290 SDValue Src2 = Node->getVal();
5291 SDLoc DL(Src2);
5292 SDValue NegSrc2 =
5293 DAG.getNode(ISD::SUB, DL, MemVT, DAG.getConstant(0, DL, MemVT), Src2);
5294 return DAG.getAtomic(ISD::ATOMIC_LOAD_ADD, DL, MemVT,
5295 Node->getChain(), Node->getBasePtr(), NegSrc2,
5296 Node->getMemOperand());
5297 }
5298
5299 return lowerATOMIC_LOAD_OP(Op, DAG, SystemZISD::ATOMIC_LOADW_SUB);
5300}
5301
5302// Lower 8/16/32/64-bit ATOMIC_CMP_SWAP_WITH_SUCCESS node.
5303SDValue SystemZTargetLowering::lowerATOMIC_CMP_SWAP(SDValue Op,
5304 SelectionDAG &DAG) const {
5305 auto *Node = cast<AtomicSDNode>(Op.getNode());
5306 SDValue ChainIn = Node->getOperand(0);
5307 SDValue Addr = Node->getOperand(1);
5308 SDValue CmpVal = Node->getOperand(2);
5309 SDValue SwapVal = Node->getOperand(3);
5310 MachineMemOperand *MMO = Node->getMemOperand();
5311 SDLoc DL(Node);
5312
5313 if (Node->getMemoryVT() == MVT::i128) {
5314 // Use same code to handle both legal and non-legal i128 types.
5316 LowerOperationWrapper(Node, Results, DAG);
5317 return DAG.getMergeValues(Results, DL);
5318 }
5319
5320 // We have native support for 32-bit and 64-bit compare and swap, but we
5321 // still need to expand extracting the "success" result from the CC.
5322 EVT NarrowVT = Node->getMemoryVT();
5323 EVT WideVT = NarrowVT == MVT::i64 ? MVT::i64 : MVT::i32;
5324 if (NarrowVT == WideVT) {
5325 SDVTList Tys = DAG.getVTList(WideVT, MVT::i32, MVT::Other);
5326 SDValue Ops[] = { ChainIn, Addr, CmpVal, SwapVal };
5327 SDValue AtomicOp = DAG.getMemIntrinsicNode(SystemZISD::ATOMIC_CMP_SWAP,
5328 DL, Tys, Ops, NarrowVT, MMO);
5329 SDValue Success = emitSETCC(DAG, DL, AtomicOp.getValue(1),
5331
5332 DAG.ReplaceAllUsesOfValueWith(Op.getValue(0), AtomicOp.getValue(0));
5333 DAG.ReplaceAllUsesOfValueWith(Op.getValue(1), Success);
5334 DAG.ReplaceAllUsesOfValueWith(Op.getValue(2), AtomicOp.getValue(2));
5335 return SDValue();
5336 }
5337
5338 // Convert 8-bit and 16-bit compare and swap to a loop, implemented
5339 // via a fullword ATOMIC_CMP_SWAPW operation.
5340 int64_t BitSize = NarrowVT.getSizeInBits();
5341
5342 SDValue AlignedAddr, BitShift, NegBitShift;
5343 getCSAddressAndShifts(Addr, DAG, DL, AlignedAddr, BitShift, NegBitShift);
5344
5345 // Construct the ATOMIC_CMP_SWAPW node.
5346 SDVTList VTList = DAG.getVTList(WideVT, MVT::i32, MVT::Other);
5347 SDValue Ops[] = { ChainIn, AlignedAddr, CmpVal, SwapVal, BitShift,
5348 NegBitShift, DAG.getConstant(BitSize, DL, WideVT) };
5349 SDValue AtomicOp = DAG.getMemIntrinsicNode(SystemZISD::ATOMIC_CMP_SWAPW, DL,
5350 VTList, Ops, NarrowVT, MMO);
5351 SDValue Success = emitSETCC(DAG, DL, AtomicOp.getValue(1),
5353
5354 // emitAtomicCmpSwapW() will zero extend the result (original value).
5355 SDValue OrigVal = DAG.getNode(ISD::AssertZext, DL, WideVT, AtomicOp.getValue(0),
5356 DAG.getValueType(NarrowVT));
5357 DAG.ReplaceAllUsesOfValueWith(Op.getValue(0), OrigVal);
5358 DAG.ReplaceAllUsesOfValueWith(Op.getValue(1), Success);
5359 DAG.ReplaceAllUsesOfValueWith(Op.getValue(2), AtomicOp.getValue(2));
5360 return SDValue();
5361}
5362
5364SystemZTargetLowering::getTargetMMOFlags(const Instruction &I) const {
5365 // Because of how we convert atomic_load and atomic_store to normal loads and
5366 // stores in the DAG, we need to ensure that the MMOs are marked volatile
5367 // since DAGCombine hasn't been updated to account for atomic, but non
5368 // volatile loads. (See D57601)
5369 if (auto *SI = dyn_cast<StoreInst>(&I))
5370 if (SI->isAtomic())
5372 if (auto *LI = dyn_cast<LoadInst>(&I))
5373 if (LI->isAtomic())
5375 if (auto *AI = dyn_cast<AtomicRMWInst>(&I))
5376 if (AI->isAtomic())
5378 if (auto *AI = dyn_cast<AtomicCmpXchgInst>(&I))
5379 if (AI->isAtomic())
5382}
5383
5384SDValue SystemZTargetLowering::lowerSTACKSAVE(SDValue Op,
5385 SelectionDAG &DAG) const {
5387 auto *Regs = Subtarget.getSpecialRegisters();
5389 report_fatal_error("Variable-sized stack allocations are not supported "
5390 "in GHC calling convention");
5391 return DAG.getCopyFromReg(Op.getOperand(0), SDLoc(Op),
5392 Regs->getStackPointerRegister(), Op.getValueType());
5393}
5394
5395SDValue SystemZTargetLowering::lowerSTACKRESTORE(SDValue Op,
5396 SelectionDAG &DAG) const {
5398 auto *Regs = Subtarget.getSpecialRegisters();
5399 bool StoreBackchain = MF.getSubtarget<SystemZSubtarget>().hasBackChain();
5400
5402 report_fatal_error("Variable-sized stack allocations are not supported "
5403 "in GHC calling convention");
5404
5405 SDValue Chain = Op.getOperand(0);
5406 SDValue NewSP = Op.getOperand(1);
5407 SDValue Backchain;
5408 SDLoc DL(Op);
5409
5410 if (StoreBackchain) {
5411 SDValue OldSP = DAG.getCopyFromReg(
5412 Chain, DL, Regs->getStackPointerRegister(), MVT::i64);
5413 Backchain = DAG.getLoad(MVT::i64, DL, Chain, getBackchainAddress(OldSP, DAG),
5414 MachinePointerInfo());
5415 }
5416
5417 Chain = DAG.getCopyToReg(Chain, DL, Regs->getStackPointerRegister(), NewSP);
5418
5419 if (StoreBackchain)
5420 Chain = DAG.getStore(Chain, DL, Backchain, getBackchainAddress(NewSP, DAG),
5421 MachinePointerInfo());
5422
5423 return Chain;
5424}
5425
5426SDValue SystemZTargetLowering::lowerPREFETCH(SDValue Op,
5427 SelectionDAG &DAG) const {
5428 bool IsData = Op.getConstantOperandVal(4);
5429 if (!IsData)
5430 // Just preserve the chain.
5431 return Op.getOperand(0);
5432
5433 SDLoc DL(Op);
5434 bool IsWrite = Op.getConstantOperandVal(2);
5435 unsigned Code = IsWrite ? SystemZ::PFD_WRITE : SystemZ::PFD_READ;
5436 auto *Node = cast<MemIntrinsicSDNode>(Op.getNode());
5437 SDValue Ops[] = {Op.getOperand(0), DAG.getTargetConstant(Code, DL, MVT::i32),
5438 Op.getOperand(1)};
5439 return DAG.getMemIntrinsicNode(SystemZISD::PREFETCH, DL,
5440 Node->getVTList(), Ops,
5441 Node->getMemoryVT(), Node->getMemOperand());
5442}
5443
5444SDValue
5445SystemZTargetLowering::lowerINTRINSIC_W_CHAIN(SDValue Op,
5446 SelectionDAG &DAG) const {
5447 unsigned Opcode, CCValid;
5448 if (isIntrinsicWithCCAndChain(Op, Opcode, CCValid)) {
5449 assert(Op->getNumValues() == 2 && "Expected only CC result and chain");
5450 SDNode *Node = emitIntrinsicWithCCAndChain(DAG, Op, Opcode);
5451 SDValue CC = getCCResult(DAG, SDValue(Node, 0));
5452 DAG.ReplaceAllUsesOfValueWith(SDValue(Op.getNode(), 0), CC);
5453 return SDValue();
5454 }
5455
5456 return SDValue();
5457}
5458
5459SDValue
5460SystemZTargetLowering::lowerINTRINSIC_WO_CHAIN(SDValue Op,
5461 SelectionDAG &DAG) const {
5462 unsigned Opcode, CCValid;
5463 if (isIntrinsicWithCC(Op, Opcode, CCValid)) {
5464 SDNode *Node = emitIntrinsicWithCC(DAG, Op, Opcode);
5465 if (Op->getNumValues() == 1)
5466 return getCCResult(DAG, SDValue(Node, 0));
5467 assert(Op->getNumValues() == 2 && "Expected a CC and non-CC result");
5468 return DAG.getNode(ISD::MERGE_VALUES, SDLoc(Op), Op->getVTList(),
5469 SDValue(Node, 0), getCCResult(DAG, SDValue(Node, 1)));
5470 }
5471
5472 unsigned Id = Op.getConstantOperandVal(0);
5473 switch (Id) {
5474 case Intrinsic::thread_pointer:
5475 return lowerThreadPointer(SDLoc(Op), DAG);
5476
5477 case Intrinsic::s390_vpdi:
5478 return DAG.getNode(SystemZISD::PERMUTE_DWORDS, SDLoc(Op), Op.getValueType(),
5479 Op.getOperand(1), Op.getOperand(2), Op.getOperand(3));
5480
5481 case Intrinsic::s390_vperm:
5482 return DAG.getNode(SystemZISD::PERMUTE, SDLoc(Op), Op.getValueType(),
5483 Op.getOperand(1), Op.getOperand(2), Op.getOperand(3));
5484
5485 case Intrinsic::s390_vuphb:
5486 case Intrinsic::s390_vuphh:
5487 case Intrinsic::s390_vuphf:
5488 case Intrinsic::s390_vuphg:
5489 return DAG.getNode(SystemZISD::UNPACK_HIGH, SDLoc(Op), Op.getValueType(),
5490 Op.getOperand(1));
5491
5492 case Intrinsic::s390_vuplhb:
5493 case Intrinsic::s390_vuplhh:
5494 case Intrinsic::s390_vuplhf:
5495 case Intrinsic::s390_vuplhg:
5496 return DAG.getNode(SystemZISD::UNPACKL_HIGH, SDLoc(Op), Op.getValueType(),
5497 Op.getOperand(1));
5498
5499 case Intrinsic::s390_vuplb:
5500 case Intrinsic::s390_vuplhw:
5501 case Intrinsic::s390_vuplf:
5502 case Intrinsic::s390_vuplg:
5503 return DAG.getNode(SystemZISD::UNPACK_LOW, SDLoc(Op), Op.getValueType(),
5504 Op.getOperand(1));
5505
5506 case Intrinsic::s390_vupllb:
5507 case Intrinsic::s390_vupllh:
5508 case Intrinsic::s390_vupllf:
5509 case Intrinsic::s390_vupllg:
5510 return DAG.getNode(SystemZISD::UNPACKL_LOW, SDLoc(Op), Op.getValueType(),
5511 Op.getOperand(1));
5512
5513 case Intrinsic::s390_vsumb:
5514 case Intrinsic::s390_vsumh:
5515 case Intrinsic::s390_vsumgh:
5516 case Intrinsic::s390_vsumgf:
5517 case Intrinsic::s390_vsumqf:
5518 case Intrinsic::s390_vsumqg:
5519 return DAG.getNode(SystemZISD::VSUM, SDLoc(Op), Op.getValueType(),
5520 Op.getOperand(1), Op.getOperand(2));
5521
5522 case Intrinsic::s390_vaq:
5523 return DAG.getNode(ISD::ADD, SDLoc(Op), Op.getValueType(),
5524 Op.getOperand(1), Op.getOperand(2));
5525 case Intrinsic::s390_vaccb:
5526 case Intrinsic::s390_vacch:
5527 case Intrinsic::s390_vaccf:
5528 case Intrinsic::s390_vaccg:
5529 case Intrinsic::s390_vaccq:
5530 return DAG.getNode(SystemZISD::VACC, SDLoc(Op), Op.getValueType(),
5531 Op.getOperand(1), Op.getOperand(2));
5532 case Intrinsic::s390_vacq:
5533 return DAG.getNode(SystemZISD::VAC, SDLoc(Op), Op.getValueType(),
5534 Op.getOperand(1), Op.getOperand(2), Op.getOperand(3));
5535 case Intrinsic::s390_vacccq:
5536 return DAG.getNode(SystemZISD::VACCC, SDLoc(Op), Op.getValueType(),
5537 Op.getOperand(1), Op.getOperand(2), Op.getOperand(3));
5538
5539 case Intrinsic::s390_vsq:
5540 return DAG.getNode(ISD::SUB, SDLoc(Op), Op.getValueType(),
5541 Op.getOperand(1), Op.getOperand(2));
5542 case Intrinsic::s390_vscbib:
5543 case Intrinsic::s390_vscbih:
5544 case Intrinsic::s390_vscbif:
5545 case Intrinsic::s390_vscbig:
5546 case Intrinsic::s390_vscbiq:
5547 return DAG.getNode(SystemZISD::VSCBI, SDLoc(Op), Op.getValueType(),
5548 Op.getOperand(1), Op.getOperand(2));
5549 case Intrinsic::s390_vsbiq:
5550 return DAG.getNode(SystemZISD::VSBI, SDLoc(Op), Op.getValueType(),
5551 Op.getOperand(1), Op.getOperand(2), Op.getOperand(3));
5552 case Intrinsic::s390_vsbcbiq:
5553 return DAG.getNode(SystemZISD::VSBCBI, SDLoc(Op), Op.getValueType(),
5554 Op.getOperand(1), Op.getOperand(2), Op.getOperand(3));
5555
5556 case Intrinsic::s390_vmhb:
5557 case Intrinsic::s390_vmhh:
5558 case Intrinsic::s390_vmhf:
5559 case Intrinsic::s390_vmhg:
5560 case Intrinsic::s390_vmhq:
5561 return DAG.getNode(ISD::MULHS, SDLoc(Op), Op.getValueType(),
5562 Op.getOperand(1), Op.getOperand(2));
5563 case Intrinsic::s390_vmlhb:
5564 case Intrinsic::s390_vmlhh:
5565 case Intrinsic::s390_vmlhf:
5566 case Intrinsic::s390_vmlhg:
5567 case Intrinsic::s390_vmlhq:
5568 return DAG.getNode(ISD::MULHU, SDLoc(Op), Op.getValueType(),
5569 Op.getOperand(1), Op.getOperand(2));
5570
5571 case Intrinsic::s390_vmahb:
5572 case Intrinsic::s390_vmahh:
5573 case Intrinsic::s390_vmahf:
5574 case Intrinsic::s390_vmahg:
5575 case Intrinsic::s390_vmahq:
5576 return DAG.getNode(SystemZISD::VMAH, SDLoc(Op), Op.getValueType(),
5577 Op.getOperand(1), Op.getOperand(2), Op.getOperand(3));
5578 case Intrinsic::s390_vmalhb:
5579 case Intrinsic::s390_vmalhh:
5580 case Intrinsic::s390_vmalhf:
5581 case Intrinsic::s390_vmalhg:
5582 case Intrinsic::s390_vmalhq:
5583 return DAG.getNode(SystemZISD::VMALH, SDLoc(Op), Op.getValueType(),
5584 Op.getOperand(1), Op.getOperand(2), Op.getOperand(3));
5585
5586 case Intrinsic::s390_vmeb:
5587 case Intrinsic::s390_vmeh:
5588 case Intrinsic::s390_vmef:
5589 case Intrinsic::s390_vmeg:
5590 return DAG.getNode(SystemZISD::VME, SDLoc(Op), Op.getValueType(),
5591 Op.getOperand(1), Op.getOperand(2));
5592 case Intrinsic::s390_vmleb:
5593 case Intrinsic::s390_vmleh:
5594 case Intrinsic::s390_vmlef:
5595 case Intrinsic::s390_vmleg:
5596 return DAG.getNode(SystemZISD::VMLE, SDLoc(Op), Op.getValueType(),
5597 Op.getOperand(1), Op.getOperand(2));
5598 case Intrinsic::s390_vmob:
5599 case Intrinsic::s390_vmoh:
5600 case Intrinsic::s390_vmof:
5601 case Intrinsic::s390_vmog:
5602 return DAG.getNode(SystemZISD::VMO, SDLoc(Op), Op.getValueType(),
5603 Op.getOperand(1), Op.getOperand(2));
5604 case Intrinsic::s390_vmlob:
5605 case Intrinsic::s390_vmloh:
5606 case Intrinsic::s390_vmlof:
5607 case Intrinsic::s390_vmlog:
5608 return DAG.getNode(SystemZISD::VMLO, SDLoc(Op), Op.getValueType(),
5609 Op.getOperand(1), Op.getOperand(2));
5610
5611 case Intrinsic::s390_vmaeb:
5612 case Intrinsic::s390_vmaeh:
5613 case Intrinsic::s390_vmaef:
5614 case Intrinsic::s390_vmaeg:
5615 return DAG.getNode(ISD::ADD, SDLoc(Op), Op.getValueType(),
5616 DAG.getNode(SystemZISD::VME, SDLoc(Op), Op.getValueType(),
5617 Op.getOperand(1), Op.getOperand(2)),
5618 Op.getOperand(3));
5619 case Intrinsic::s390_vmaleb:
5620 case Intrinsic::s390_vmaleh:
5621 case Intrinsic::s390_vmalef:
5622 case Intrinsic::s390_vmaleg:
5623 return DAG.getNode(ISD::ADD, SDLoc(Op), Op.getValueType(),
5624 DAG.getNode(SystemZISD::VMLE, SDLoc(Op), Op.getValueType(),
5625 Op.getOperand(1), Op.getOperand(2)),
5626 Op.getOperand(3));
5627 case Intrinsic::s390_vmaob:
5628 case Intrinsic::s390_vmaoh:
5629 case Intrinsic::s390_vmaof:
5630 case Intrinsic::s390_vmaog:
5631 return DAG.getNode(ISD::ADD, SDLoc(Op), Op.getValueType(),
5632 DAG.getNode(SystemZISD::VMO, SDLoc(Op), Op.getValueType(),
5633 Op.getOperand(1), Op.getOperand(2)),
5634 Op.getOperand(3));
5635 case Intrinsic::s390_vmalob:
5636 case Intrinsic::s390_vmaloh:
5637 case Intrinsic::s390_vmalof:
5638 case Intrinsic::s390_vmalog:
5639 return DAG.getNode(ISD::ADD, SDLoc(Op), Op.getValueType(),
5640 DAG.getNode(SystemZISD::VMLO, SDLoc(Op), Op.getValueType(),
5641 Op.getOperand(1), Op.getOperand(2)),
5642 Op.getOperand(3));
5643 }
5644
5645 return SDValue();
5646}
5647
5648namespace {
5649// Says that SystemZISD operation Opcode can be used to perform the equivalent
5650// of a VPERM with permute vector Bytes. If Opcode takes three operands,
5651// Operand is the constant third operand, otherwise it is the number of
5652// bytes in each element of the result.
5653struct Permute {
5654 unsigned Opcode;
5655 unsigned Operand;
5656 unsigned char Bytes[SystemZ::VectorBytes];
5657};
5658}
5659
5660static const Permute PermuteForms[] = {
5661 // VMRHG
5662 { SystemZISD::MERGE_HIGH, 8,
5663 { 0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 23 } },
5664 // VMRHF
5665 { SystemZISD::MERGE_HIGH, 4,
5666 { 0, 1, 2, 3, 16, 17, 18, 19, 4, 5, 6, 7, 20, 21, 22, 23 } },
5667 // VMRHH
5668 { SystemZISD::MERGE_HIGH, 2,
5669 { 0, 1, 16, 17, 2, 3, 18, 19, 4, 5, 20, 21, 6, 7, 22, 23 } },
5670 // VMRHB
5671 { SystemZISD::MERGE_HIGH, 1,
5672 { 0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23 } },
5673 // VMRLG
5674 { SystemZISD::MERGE_LOW, 8,
5675 { 8, 9, 10, 11, 12, 13, 14, 15, 24, 25, 26, 27, 28, 29, 30, 31 } },
5676 // VMRLF
5677 { SystemZISD::MERGE_LOW, 4,
5678 { 8, 9, 10, 11, 24, 25, 26, 27, 12, 13, 14, 15, 28, 29, 30, 31 } },
5679 // VMRLH
5680 { SystemZISD::MERGE_LOW, 2,
5681 { 8, 9, 24, 25, 10, 11, 26, 27, 12, 13, 28, 29, 14, 15, 30, 31 } },
5682 // VMRLB
5683 { SystemZISD::MERGE_LOW, 1,
5684 { 8, 24, 9, 25, 10, 26, 11, 27, 12, 28, 13, 29, 14, 30, 15, 31 } },
5685 // VPKG
5686 { SystemZISD::PACK, 4,
5687 { 4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31 } },
5688 // VPKF
5689 { SystemZISD::PACK, 2,
5690 { 2, 3, 6, 7, 10, 11, 14, 15, 18, 19, 22, 23, 26, 27, 30, 31 } },
5691 // VPKH
5692 { SystemZISD::PACK, 1,
5693 { 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31 } },
5694 // VPDI V1, V2, 4 (low half of V1, high half of V2)
5695 { SystemZISD::PERMUTE_DWORDS, 4,
5696 { 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 } },
5697 // VPDI V1, V2, 1 (high half of V1, low half of V2)
5698 { SystemZISD::PERMUTE_DWORDS, 1,
5699 { 0, 1, 2, 3, 4, 5, 6, 7, 24, 25, 26, 27, 28, 29, 30, 31 } }
5700};
5701
5702// Called after matching a vector shuffle against a particular pattern.
5703// Both the original shuffle and the pattern have two vector operands.
5704// OpNos[0] is the operand of the original shuffle that should be used for
5705// operand 0 of the pattern, or -1 if operand 0 of the pattern can be anything.
5706// OpNos[1] is the same for operand 1 of the pattern. Resolve these -1s and
5707// set OpNo0 and OpNo1 to the shuffle operands that should actually be used
5708// for operands 0 and 1 of the pattern.
5709static bool chooseShuffleOpNos(int *OpNos, unsigned &OpNo0, unsigned &OpNo1) {
5710 if (OpNos[0] < 0) {
5711 if (OpNos[1] < 0)
5712 return false;
5713 OpNo0 = OpNo1 = OpNos[1];
5714 } else if (OpNos[1] < 0) {
5715 OpNo0 = OpNo1 = OpNos[0];
5716 } else {
5717 OpNo0 = OpNos[0];
5718 OpNo1 = OpNos[1];
5719 }
5720 return true;
5721}
5722
5723// Bytes is a VPERM-like permute vector, except that -1 is used for
5724// undefined bytes. Return true if the VPERM can be implemented using P.
5725// When returning true set OpNo0 to the VPERM operand that should be
5726// used for operand 0 of P and likewise OpNo1 for operand 1 of P.
5727//
5728// For example, if swapping the VPERM operands allows P to match, OpNo0
5729// will be 1 and OpNo1 will be 0. If instead Bytes only refers to one
5730// operand, but rewriting it to use two duplicated operands allows it to
5731// match P, then OpNo0 and OpNo1 will be the same.
5732static bool matchPermute(const SmallVectorImpl<int> &Bytes, const Permute &P,
5733 unsigned &OpNo0, unsigned &OpNo1) {
5734 int OpNos[] = { -1, -1 };
5735 for (unsigned I = 0; I < SystemZ::VectorBytes; ++I) {
5736 int Elt = Bytes[I];
5737 if (Elt >= 0) {
5738 // Make sure that the two permute vectors use the same suboperand
5739 // byte number. Only the operand numbers (the high bits) are
5740 // allowed to differ.
5741 if ((Elt ^ P.Bytes[I]) & (SystemZ::VectorBytes - 1))
5742 return false;
5743 int ModelOpNo = P.Bytes[I] / SystemZ::VectorBytes;
5744 int RealOpNo = unsigned(Elt) / SystemZ::VectorBytes;
5745 // Make sure that the operand mappings are consistent with previous
5746 // elements.
5747 if (OpNos[ModelOpNo] == 1 - RealOpNo)
5748 return false;
5749 OpNos[ModelOpNo] = RealOpNo;
5750 }
5751 }
5752 return chooseShuffleOpNos(OpNos, OpNo0, OpNo1);
5753}
5754
5755// As above, but search for a matching permute.
5756static const Permute *matchPermute(const SmallVectorImpl<int> &Bytes,
5757 unsigned &OpNo0, unsigned &OpNo1) {
5758 for (auto &P : PermuteForms)
5759 if (matchPermute(Bytes, P, OpNo0, OpNo1))
5760 return &P;
5761 return nullptr;
5762}
5763
5764// Bytes is a VPERM-like permute vector, except that -1 is used for
5765// undefined bytes. This permute is an operand of an outer permute.
5766// See whether redistributing the -1 bytes gives a shuffle that can be
5767// implemented using P. If so, set Transform to a VPERM-like permute vector
5768// that, when applied to the result of P, gives the original permute in Bytes.
5770 const Permute &P,
5771 SmallVectorImpl<int> &Transform) {
5772 unsigned To = 0;
5773 for (unsigned From = 0; From < SystemZ::VectorBytes; ++From) {
5774 int Elt = Bytes[From];
5775 if (Elt < 0)
5776 // Byte number From of the result is undefined.
5777 Transform[From] = -1;
5778 else {
5779 while (P.Bytes[To] != Elt) {
5780 To += 1;
5781 if (To == SystemZ::VectorBytes)
5782 return false;
5783 }
5784 Transform[From] = To;
5785 }
5786 }
5787 return true;
5788}
5789
5790// As above, but search for a matching permute.
5791static const Permute *matchDoublePermute(const SmallVectorImpl<int> &Bytes,
5792 SmallVectorImpl<int> &Transform) {
5793 for (auto &P : PermuteForms)
5794 if (matchDoublePermute(Bytes, P, Transform))
5795 return &P;
5796 return nullptr;
5797}
5798
5799// Convert the mask of the given shuffle op into a byte-level mask,
5800// as if it had type vNi8.
5801static bool getVPermMask(SDValue ShuffleOp,
5802 SmallVectorImpl<int> &Bytes) {
5803 EVT VT = ShuffleOp.getValueType();
5804 unsigned NumElements = VT.getVectorNumElements();
5805 unsigned BytesPerElement = VT.getVectorElementType().getStoreSize();
5806
5807 if (auto *VSN = dyn_cast<ShuffleVectorSDNode>(ShuffleOp)) {
5808 Bytes.resize(NumElements * BytesPerElement, -1);
5809 for (unsigned I = 0; I < NumElements; ++I) {
5810 int Index = VSN->getMaskElt(I);
5811 if (Index >= 0)
5812 for (unsigned J = 0; J < BytesPerElement; ++J)
5813 Bytes[I * BytesPerElement + J] = Index * BytesPerElement + J;
5814 }
5815 return true;
5816 }
5817 if (SystemZISD::SPLAT == ShuffleOp.getOpcode() &&
5818 isa<ConstantSDNode>(ShuffleOp.getOperand(1))) {
5819 unsigned Index = ShuffleOp.getConstantOperandVal(1);
5820 Bytes.resize(NumElements * BytesPerElement, -1);
5821 for (unsigned I = 0; I < NumElements; ++I)
5822 for (unsigned J = 0; J < BytesPerElement; ++J)
5823 Bytes[I * BytesPerElement + J] = Index * BytesPerElement + J;
5824 return true;
5825 }
5826 return false;
5827}
5828
5829// Bytes is a VPERM-like permute vector, except that -1 is used for
5830// undefined bytes. See whether bytes [Start, Start + BytesPerElement) of
5831// the result come from a contiguous sequence of bytes from one input.
5832// Set Base to the selector for the first byte if so.
5833static bool getShuffleInput(const SmallVectorImpl<int> &Bytes, unsigned Start,
5834 unsigned BytesPerElement, int &Base) {
5835 Base = -1;
5836 for (unsigned I = 0; I < BytesPerElement; ++I) {
5837 if (Bytes[Start + I] >= 0) {
5838 unsigned Elem = Bytes[Start + I];
5839 if (Base < 0) {
5840 Base = Elem - I;
5841 // Make sure the bytes would come from one input operand.
5842 if (unsigned(Base) % Bytes.size() + BytesPerElement > Bytes.size())
5843 return false;
5844 } else if (unsigned(Base) != Elem - I)
5845 return false;
5846 }
5847 }
5848 return true;
5849}
5850
5851// Bytes is a VPERM-like permute vector, except that -1 is used for
5852// undefined bytes. Return true if it can be performed using VSLDB.
5853// When returning true, set StartIndex to the shift amount and OpNo0
5854// and OpNo1 to the VPERM operands that should be used as the first
5855// and second shift operand respectively.
5857 unsigned &StartIndex, unsigned &OpNo0,
5858 unsigned &OpNo1) {
5859 int OpNos[] = { -1, -1 };
5860 int Shift = -1;
5861 for (unsigned I = 0; I < 16; ++I) {
5862 int Index = Bytes[I];
5863 if (Index >= 0) {
5864 int ExpectedShift = (Index - I) % SystemZ::VectorBytes;
5865 int ModelOpNo = unsigned(ExpectedShift + I) / SystemZ::VectorBytes;
5866 int RealOpNo = unsigned(Index) / SystemZ::VectorBytes;
5867 if (Shift < 0)
5868 Shift = ExpectedShift;
5869 else if (Shift != ExpectedShift)
5870 return false;
5871 // Make sure that the operand mappings are consistent with previous
5872 // elements.
5873 if (OpNos[ModelOpNo] == 1 - RealOpNo)
5874 return false;
5875 OpNos[ModelOpNo] = RealOpNo;
5876 }
5877 }
5878 StartIndex = Shift;
5879 return chooseShuffleOpNos(OpNos, OpNo0, OpNo1);
5880}
5881
5882// Create a node that performs P on operands Op0 and Op1, casting the
5883// operands to the appropriate type. The type of the result is determined by P.
5885 const Permute &P, SDValue Op0, SDValue Op1) {
5886 // VPDI (PERMUTE_DWORDS) always operates on v2i64s. The input
5887 // elements of a PACK are twice as wide as the outputs.
5888 unsigned InBytes = (P.Opcode == SystemZISD::PERMUTE_DWORDS ? 8 :
5889 P.Opcode == SystemZISD::PACK ? P.Operand * 2 :
5890 P.Operand);
5891 // Cast both operands to the appropriate type.
5892 MVT InVT = MVT::getVectorVT(MVT::getIntegerVT(InBytes * 8),
5893 SystemZ::VectorBytes / InBytes);
5894 Op0 = DAG.getNode(ISD::BITCAST, DL, InVT, Op0);
5895 Op1 = DAG.getNode(ISD::BITCAST, DL, InVT, Op1);
5896 SDValue Op;
5897 if (P.Opcode == SystemZISD::PERMUTE_DWORDS) {
5898 SDValue Op2 = DAG.getTargetConstant(P.Operand, DL, MVT::i32);
5899 Op = DAG.getNode(SystemZISD::PERMUTE_DWORDS, DL, InVT, Op0, Op1, Op2);
5900 } else if (P.Opcode == SystemZISD::PACK) {
5901 MVT OutVT = MVT::getVectorVT(MVT::getIntegerVT(P.Operand * 8),
5902 SystemZ::VectorBytes / P.Operand);
5903 Op = DAG.getNode(SystemZISD::PACK, DL, OutVT, Op0, Op1);
5904 } else {
5905 Op = DAG.getNode(P.Opcode, DL, InVT, Op0, Op1);
5906 }
5907 return Op;
5908}
5909
5910static bool isZeroVector(SDValue N) {
5911 if (N->getOpcode() == ISD::BITCAST)
5912 N = N->getOperand(0);
5913 if (N->getOpcode() == ISD::SPLAT_VECTOR)
5914 if (auto *Op = dyn_cast<ConstantSDNode>(N->getOperand(0)))
5915 return Op->getZExtValue() == 0;
5916 return ISD::isBuildVectorAllZeros(N.getNode());
5917}
5918
5919// Return the index of the zero/undef vector, or UINT32_MAX if not found.
5920static uint32_t findZeroVectorIdx(SDValue *Ops, unsigned Num) {
5921 for (unsigned I = 0; I < Num ; I++)
5922 if (isZeroVector(Ops[I]))
5923 return I;
5924 return UINT32_MAX;
5925}
5926
5927// Bytes is a VPERM-like permute vector, except that -1 is used for
5928// undefined bytes. Implement it on operands Ops[0] and Ops[1] using
5929// VSLDB or VPERM.
5931 SDValue *Ops,
5932 const SmallVectorImpl<int> &Bytes) {
5933 for (unsigned I = 0; I < 2; ++I)
5934 Ops[I] = DAG.getNode(ISD::BITCAST, DL, MVT::v16i8, Ops[I]);
5935
5936 // First see whether VSLDB can be used.
5937 unsigned StartIndex, OpNo0, OpNo1;
5938 if (isShlDoublePermute(Bytes, StartIndex, OpNo0, OpNo1))
5939 return DAG.getNode(SystemZISD::SHL_DOUBLE, DL, MVT::v16i8, Ops[OpNo0],
5940 Ops[OpNo1],
5941 DAG.getTargetConstant(StartIndex, DL, MVT::i32));
5942
5943 // Fall back on VPERM. Construct an SDNode for the permute vector. Try to
5944 // eliminate a zero vector by reusing any zero index in the permute vector.
5945 unsigned ZeroVecIdx = findZeroVectorIdx(&Ops[0], 2);
5946 if (ZeroVecIdx != UINT32_MAX) {
5947 bool MaskFirst = true;
5948 int ZeroIdx = -1;
5949 for (unsigned I = 0; I < SystemZ::VectorBytes; ++I) {
5950 unsigned OpNo = unsigned(Bytes[I]) / SystemZ::VectorBytes;
5951 unsigned Byte = unsigned(Bytes[I]) % SystemZ::VectorBytes;
5952 if (OpNo == ZeroVecIdx && I == 0) {
5953 // If the first byte is zero, use mask as first operand.
5954 ZeroIdx = 0;
5955 break;
5956 }
5957 if (OpNo != ZeroVecIdx && Byte == 0) {
5958 // If mask contains a zero, use it by placing that vector first.
5959 ZeroIdx = I + SystemZ::VectorBytes;
5960 MaskFirst = false;
5961 break;
5962 }
5963 }
5964 if (ZeroIdx != -1) {
5965 SDValue IndexNodes[SystemZ::VectorBytes];
5966 for (unsigned I = 0; I < SystemZ::VectorBytes; ++I) {
5967 if (Bytes[I] >= 0) {
5968 unsigned OpNo = unsigned(Bytes[I]) / SystemZ::VectorBytes;
5969 unsigned Byte = unsigned(Bytes[I]) % SystemZ::VectorBytes;
5970 if (OpNo == ZeroVecIdx)
5971 IndexNodes[I] = DAG.getConstant(ZeroIdx, DL, MVT::i32);
5972 else {
5973 unsigned BIdx = MaskFirst ? Byte + SystemZ::VectorBytes : Byte;
5974 IndexNodes[I] = DAG.getConstant(BIdx, DL, MVT::i32);
5975 }
5976 } else
5977 IndexNodes[I] = DAG.getUNDEF(MVT::i32);
5978 }
5979 SDValue Mask = DAG.getBuildVector(MVT::v16i8, DL, IndexNodes);
5980 SDValue Src = ZeroVecIdx == 0 ? Ops[1] : Ops[0];
5981 if (MaskFirst)
5982 return DAG.getNode(SystemZISD::PERMUTE, DL, MVT::v16i8, Mask, Src,
5983 Mask);
5984 else
5985 return DAG.getNode(SystemZISD::PERMUTE, DL, MVT::v16i8, Src, Mask,
5986 Mask);
5987 }
5988 }
5989
5990 SDValue IndexNodes[SystemZ::VectorBytes];
5991 for (unsigned I = 0; I < SystemZ::VectorBytes; ++I)
5992 if (Bytes[I] >= 0)
5993 IndexNodes[I] = DAG.getConstant(Bytes[I], DL, MVT::i32);
5994 else
5995 IndexNodes[I] = DAG.getUNDEF(MVT::i32);
5996 SDValue Op2 = DAG.getBuildVector(MVT::v16i8, DL, IndexNodes);
5997 return DAG.getNode(SystemZISD::PERMUTE, DL, MVT::v16i8, Ops[0],
5998 (!Ops[1].isUndef() ? Ops[1] : Ops[0]), Op2);
5999}
6000
6001namespace {
6002// Describes a general N-operand vector shuffle.
6003struct GeneralShuffle {
6004 GeneralShuffle(EVT vt)
6005 : VT(vt), UnpackFromEltSize(UINT_MAX), UnpackLow(false) {}
6006 void addUndef();
6007 bool add(SDValue, unsigned);
6008 SDValue getNode(SelectionDAG &, const SDLoc &);
6009 void tryPrepareForUnpack();
6010 bool unpackWasPrepared() { return UnpackFromEltSize <= 4; }
6011 SDValue insertUnpackIfPrepared(SelectionDAG &DAG, const SDLoc &DL, SDValue Op);
6012
6013 // The operands of the shuffle.
6015
6016 // Index I is -1 if byte I of the result is undefined. Otherwise the
6017 // result comes from byte Bytes[I] % SystemZ::VectorBytes of operand
6018 // Bytes[I] / SystemZ::VectorBytes.
6020
6021 // The type of the shuffle result.
6022 EVT VT;
6023
6024 // Holds a value of 1, 2 or 4 if a final unpack has been prepared for.
6025 unsigned UnpackFromEltSize;
6026 // True if the final unpack uses the low half.
6027 bool UnpackLow;
6028};
6029} // namespace
6030
6031// Add an extra undefined element to the shuffle.
6032void GeneralShuffle::addUndef() {
6033 unsigned BytesPerElement = VT.getVectorElementType().getStoreSize();
6034 for (unsigned I = 0; I < BytesPerElement; ++I)
6035 Bytes.push_back(-1);
6036}
6037
6038// Add an extra element to the shuffle, taking it from element Elem of Op.
6039// A null Op indicates a vector input whose value will be calculated later;
6040// there is at most one such input per shuffle and it always has the same
6041// type as the result. Aborts and returns false if the source vector elements
6042// of an EXTRACT_VECTOR_ELT are smaller than the destination elements. Per
6043// LLVM they become implicitly extended, but this is rare and not optimized.
6044bool GeneralShuffle::add(SDValue Op, unsigned Elem) {
6045 unsigned BytesPerElement = VT.getVectorElementType().getStoreSize();
6046
6047 // The source vector can have wider elements than the result,
6048 // either through an explicit TRUNCATE or because of type legalization.
6049 // We want the least significant part.
6050 EVT FromVT = Op.getNode() ? Op.getValueType() : VT;
6051 unsigned FromBytesPerElement = FromVT.getVectorElementType().getStoreSize();
6052
6053 // Return false if the source elements are smaller than their destination
6054 // elements.
6055 if (FromBytesPerElement < BytesPerElement)
6056 return false;
6057
6058 unsigned Byte = ((Elem * FromBytesPerElement) % SystemZ::VectorBytes +
6059 (FromBytesPerElement - BytesPerElement));
6060
6061 // Look through things like shuffles and bitcasts.
6062 while (Op.getNode()) {
6063 if (Op.getOpcode() == ISD::BITCAST)
6064 Op = Op.getOperand(0);
6065 else if (Op.getOpcode() == ISD::VECTOR_SHUFFLE && Op.hasOneUse()) {
6066 // See whether the bytes we need come from a contiguous part of one
6067 // operand.
6069 if (!getVPermMask(Op, OpBytes))
6070 break;
6071 int NewByte;
6072 if (!getShuffleInput(OpBytes, Byte, BytesPerElement, NewByte))
6073 break;
6074 if (NewByte < 0) {
6075 addUndef();
6076 return true;
6077 }
6078 Op = Op.getOperand(unsigned(NewByte) / SystemZ::VectorBytes);
6079 Byte = unsigned(NewByte) % SystemZ::VectorBytes;
6080 } else if (Op.isUndef()) {
6081 addUndef();
6082 return true;
6083 } else
6084 break;
6085 }
6086
6087 // Make sure that the source of the extraction is in Ops.
6088 unsigned OpNo = 0;
6089 for (; OpNo < Ops.size(); ++OpNo)
6090 if (Ops[OpNo] == Op)
6091 break;
6092 if (OpNo == Ops.size())
6093 Ops.push_back(Op);
6094
6095 // Add the element to Bytes.
6096 unsigned Base = OpNo * SystemZ::VectorBytes + Byte;
6097 for (unsigned I = 0; I < BytesPerElement; ++I)
6098 Bytes.push_back(Base + I);
6099
6100 return true;
6101}
6102
6103// Return SDNodes for the completed shuffle.
6104SDValue GeneralShuffle::getNode(SelectionDAG &DAG, const SDLoc &DL) {
6105 assert(Bytes.size() == SystemZ::VectorBytes && "Incomplete vector");
6106
6107 if (Ops.size() == 0)
6108 return DAG.getUNDEF(VT);
6109
6110 // Use a single unpack if possible as the last operation.
6111 tryPrepareForUnpack();
6112
6113 // Make sure that there are at least two shuffle operands.
6114 if (Ops.size() == 1)
6115 Ops.push_back(DAG.getUNDEF(MVT::v16i8));
6116
6117 // Create a tree of shuffles, deferring root node until after the loop.
6118 // Try to redistribute the undefined elements of non-root nodes so that
6119 // the non-root shuffles match something like a pack or merge, then adjust
6120 // the parent node's permute vector to compensate for the new order.
6121 // Among other things, this copes with vectors like <2 x i16> that were
6122 // padded with undefined elements during type legalization.
6123 //
6124 // In the best case this redistribution will lead to the whole tree
6125 // using packs and merges. It should rarely be a loss in other cases.
6126 unsigned Stride = 1;
6127 for (; Stride * 2 < Ops.size(); Stride *= 2) {
6128 for (unsigned I = 0; I < Ops.size() - Stride; I += Stride * 2) {
6129 SDValue SubOps[] = { Ops[I], Ops[I + Stride] };
6130
6131 // Create a mask for just these two operands.
6133 for (unsigned J = 0; J < SystemZ::VectorBytes; ++J) {
6134 unsigned OpNo = unsigned(Bytes[J]) / SystemZ::VectorBytes;
6135 unsigned Byte = unsigned(Bytes[J]) % SystemZ::VectorBytes;
6136 if (OpNo == I)
6137 NewBytes[J] = Byte;
6138 else if (OpNo == I + Stride)
6139 NewBytes[J] = SystemZ::VectorBytes + Byte;
6140 else
6141 NewBytes[J] = -1;
6142 }
6143 // See if it would be better to reorganize NewMask to avoid using VPERM.
6145 if (const Permute *P = matchDoublePermute(NewBytes, NewBytesMap)) {
6146 Ops[I] = getPermuteNode(DAG, DL, *P, SubOps[0], SubOps[1]);
6147 // Applying NewBytesMap to Ops[I] gets back to NewBytes.
6148 for (unsigned J = 0; J < SystemZ::VectorBytes; ++J) {
6149 if (NewBytes[J] >= 0) {
6150 assert(unsigned(NewBytesMap[J]) < SystemZ::VectorBytes &&
6151 "Invalid double permute");
6152 Bytes[J] = I * SystemZ::VectorBytes + NewBytesMap[J];
6153 } else
6154 assert(NewBytesMap[J] < 0 && "Invalid double permute");
6155 }
6156 } else {
6157 // Just use NewBytes on the operands.
6158 Ops[I] = getGeneralPermuteNode(DAG, DL, SubOps, NewBytes);
6159 for (unsigned J = 0; J < SystemZ::VectorBytes; ++J)
6160 if (NewBytes[J] >= 0)
6161 Bytes[J] = I * SystemZ::VectorBytes + J;
6162 }
6163 }
6164 }
6165
6166 // Now we just have 2 inputs. Put the second operand in Ops[1].
6167 if (Stride > 1) {
6168 Ops[1] = Ops[Stride];
6169 for (unsigned I = 0; I < SystemZ::VectorBytes; ++I)
6170 if (Bytes[I] >= int(SystemZ::VectorBytes))
6171 Bytes[I] -= (Stride - 1) * SystemZ::VectorBytes;
6172 }
6173
6174 // Look for an instruction that can do the permute without resorting
6175 // to VPERM.
6176 unsigned OpNo0, OpNo1;
6177 SDValue Op;
6178 if (unpackWasPrepared() && Ops[1].isUndef())
6179 Op = Ops[0];
6180 else if (const Permute *P = matchPermute(Bytes, OpNo0, OpNo1))
6181 Op = getPermuteNode(DAG, DL, *P, Ops[OpNo0], Ops[OpNo1]);
6182 else
6183 Op = getGeneralPermuteNode(DAG, DL, &Ops[0], Bytes);
6184
6185 Op = insertUnpackIfPrepared(DAG, DL, Op);
6186
6187 return DAG.getNode(ISD::BITCAST, DL, VT, Op);
6188}
6189
6190#ifndef NDEBUG
6191static void dumpBytes(const SmallVectorImpl<int> &Bytes, std::string Msg) {
6192 dbgs() << Msg.c_str() << " { ";
6193 for (unsigned I = 0; I < Bytes.size(); I++)
6194 dbgs() << Bytes[I] << " ";
6195 dbgs() << "}\n";
6196}
6197#endif
6198
6199// If the Bytes vector matches an unpack operation, prepare to do the unpack
6200// after all else by removing the zero vector and the effect of the unpack on
6201// Bytes.
6202void GeneralShuffle::tryPrepareForUnpack() {
6203 uint32_t ZeroVecOpNo = findZeroVectorIdx(&Ops[0], Ops.size());
6204 if (ZeroVecOpNo == UINT32_MAX || Ops.size() == 1)
6205 return;
6206
6207 // Only do this if removing the zero vector reduces the depth, otherwise
6208 // the critical path will increase with the final unpack.
6209 if (Ops.size() > 2 &&
6210 Log2_32_Ceil(Ops.size()) == Log2_32_Ceil(Ops.size() - 1))
6211 return;
6212
6213 // Find an unpack that would allow removing the zero vector from Ops.
6214 UnpackFromEltSize = 1;
6215 for (; UnpackFromEltSize <= 4; UnpackFromEltSize *= 2) {
6216 bool MatchUnpack = true;
6218 for (unsigned Elt = 0; Elt < SystemZ::VectorBytes; Elt++) {
6219 unsigned ToEltSize = UnpackFromEltSize * 2;
6220 bool IsZextByte = (Elt % ToEltSize) < UnpackFromEltSize;
6221 if (!IsZextByte)
6222 SrcBytes.push_back(Bytes[Elt]);
6223 if (Bytes[Elt] != -1) {
6224 unsigned OpNo = unsigned(Bytes[Elt]) / SystemZ::VectorBytes;
6225 if (IsZextByte != (OpNo == ZeroVecOpNo)) {
6226 MatchUnpack = false;
6227 break;
6228 }
6229 }
6230 }
6231 if (MatchUnpack) {
6232 if (Ops.size() == 2) {
6233 // Don't use unpack if a single source operand needs rearrangement.
6234 bool CanUseUnpackLow = true, CanUseUnpackHigh = true;
6235 for (unsigned i = 0; i < SystemZ::VectorBytes / 2; i++) {
6236 if (SrcBytes[i] == -1)
6237 continue;
6238 if (SrcBytes[i] % 16 != int(i))
6239 CanUseUnpackHigh = false;
6240 if (SrcBytes[i] % 16 != int(i + SystemZ::VectorBytes / 2))
6241 CanUseUnpackLow = false;
6242 if (!CanUseUnpackLow && !CanUseUnpackHigh) {
6243 UnpackFromEltSize = UINT_MAX;
6244 return;
6245 }
6246 }
6247 if (!CanUseUnpackHigh)
6248 UnpackLow = true;
6249 }
6250 break;
6251 }
6252 }
6253 if (UnpackFromEltSize > 4)
6254 return;
6255
6256 LLVM_DEBUG(dbgs() << "Preparing for final unpack of element size "
6257 << UnpackFromEltSize << ". Zero vector is Op#" << ZeroVecOpNo
6258 << ".\n";
6259 dumpBytes(Bytes, "Original Bytes vector:"););
6260
6261 // Apply the unpack in reverse to the Bytes array.
6262 unsigned B = 0;
6263 if (UnpackLow) {
6264 while (B < SystemZ::VectorBytes / 2)
6265 Bytes[B++] = -1;
6266 }
6267 for (unsigned Elt = 0; Elt < SystemZ::VectorBytes;) {
6268 Elt += UnpackFromEltSize;
6269 for (unsigned i = 0; i < UnpackFromEltSize; i++, Elt++, B++)
6270 Bytes[B] = Bytes[Elt];
6271 }
6272 if (!UnpackLow) {
6273 while (B < SystemZ::VectorBytes)
6274 Bytes[B++] = -1;
6275 }
6276
6277 // Remove the zero vector from Ops
6278 Ops.erase(&Ops[ZeroVecOpNo]);
6279 for (unsigned I = 0; I < SystemZ::VectorBytes; ++I)
6280 if (Bytes[I] >= 0) {
6281 unsigned OpNo = unsigned(Bytes[I]) / SystemZ::VectorBytes;
6282 if (OpNo > ZeroVecOpNo)
6283 Bytes[I] -= SystemZ::VectorBytes;
6284 }
6285
6286 LLVM_DEBUG(dumpBytes(Bytes, "Resulting Bytes vector, zero vector removed:");
6287 dbgs() << "\n";);
6288}
6289
6290SDValue GeneralShuffle::insertUnpackIfPrepared(SelectionDAG &DAG,
6291 const SDLoc &DL,
6292 SDValue Op) {
6293 if (!unpackWasPrepared())
6294 return Op;
6295 unsigned InBits = UnpackFromEltSize * 8;
6296 EVT InVT = MVT::getVectorVT(MVT::getIntegerVT(InBits),
6297 SystemZ::VectorBits / InBits);
6298 SDValue PackedOp = DAG.getNode(ISD::BITCAST, DL, InVT, Op);
6299 unsigned OutBits = InBits * 2;
6300 EVT OutVT = MVT::getVectorVT(MVT::getIntegerVT(OutBits),
6301 SystemZ::VectorBits / OutBits);
6302 return DAG.getNode(UnpackLow ? SystemZISD::UNPACKL_LOW
6303 : SystemZISD::UNPACKL_HIGH,
6304 DL, OutVT, PackedOp);
6305}
6306
6307// Return true if the given BUILD_VECTOR is a scalar-to-vector conversion.
6309 for (unsigned I = 1, E = Op.getNumOperands(); I != E; ++I)
6310 if (!Op.getOperand(I).isUndef())
6311 return false;
6312 return true;
6313}
6314
6315// Return a vector of type VT that contains Value in the first element.
6316// The other elements don't matter.
6318 SDValue Value) {
6319 // If we have a constant, replicate it to all elements and let the
6320 // BUILD_VECTOR lowering take care of it.
6321 if (Value.getOpcode() == ISD::Constant ||
6322 Value.getOpcode() == ISD::ConstantFP) {
6324 return DAG.getBuildVector(VT, DL, Ops);
6325 }
6326 if (Value.isUndef())
6327 return DAG.getUNDEF(VT);
6328 return DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, VT, Value);
6329}
6330
6331// Return a vector of type VT in which Op0 is in element 0 and Op1 is in
6332// element 1. Used for cases in which replication is cheap.
6334 SDValue Op0, SDValue Op1) {
6335 if (Op0.isUndef()) {
6336 if (Op1.isUndef())
6337 return DAG.getUNDEF(VT);
6338 return DAG.getNode(SystemZISD::REPLICATE, DL, VT, Op1);
6339 }
6340 if (Op1.isUndef())
6341 return DAG.getNode(SystemZISD::REPLICATE, DL, VT, Op0);
6342 return DAG.getNode(SystemZISD::MERGE_HIGH, DL, VT,
6343 buildScalarToVector(DAG, DL, VT, Op0),
6344 buildScalarToVector(DAG, DL, VT, Op1));
6345}
6346
6347// Extend GPR scalars Op0 and Op1 to doublewords and return a v2i64
6348// vector for them.
6350 SDValue Op1) {
6351 if (Op0.isUndef() && Op1.isUndef())
6352 return DAG.getUNDEF(MVT::v2i64);
6353 // If one of the two inputs is undefined then replicate the other one,
6354 // in order to avoid using another register unnecessarily.
6355 if (Op0.isUndef())
6356 Op0 = Op1 = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Op1);
6357 else if (Op1.isUndef())
6358 Op0 = Op1 = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Op0);
6359 else {
6360 Op0 = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Op0);
6361 Op1 = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Op1);
6362 }
6363 return DAG.getNode(SystemZISD::JOIN_DWORDS, DL, MVT::v2i64, Op0, Op1);
6364}
6365
6366// If a BUILD_VECTOR contains some EXTRACT_VECTOR_ELTs, it's usually
6367// better to use VECTOR_SHUFFLEs on them, only using BUILD_VECTOR for
6368// the non-EXTRACT_VECTOR_ELT elements. See if the given BUILD_VECTOR
6369// would benefit from this representation and return it if so.
6371 BuildVectorSDNode *BVN) {
6372 EVT VT = BVN->getValueType(0);
6373 unsigned NumElements = VT.getVectorNumElements();
6374
6375 // Represent the BUILD_VECTOR as an N-operand VECTOR_SHUFFLE-like operation
6376 // on byte vectors. If there are non-EXTRACT_VECTOR_ELT elements that still
6377 // need a BUILD_VECTOR, add an additional placeholder operand for that
6378 // BUILD_VECTOR and store its operands in ResidueOps.
6379 GeneralShuffle GS(VT);
6381 bool FoundOne = false;
6382 for (unsigned I = 0; I < NumElements; ++I) {
6383 SDValue Op = BVN->getOperand(I);
6384 if (Op.getOpcode() == ISD::TRUNCATE)
6385 Op = Op.getOperand(0);
6386 if (Op.getOpcode() == ISD::EXTRACT_VECTOR_ELT &&
6387 Op.getOperand(1).getOpcode() == ISD::Constant) {
6388 unsigned Elem = Op.getConstantOperandVal(1);
6389 if (!GS.add(Op.getOperand(0), Elem))
6390 return SDValue();
6391 FoundOne = true;
6392 } else if (Op.isUndef()) {
6393 GS.addUndef();
6394 } else {
6395 if (!GS.add(SDValue(), ResidueOps.size()))
6396 return SDValue();
6397 ResidueOps.push_back(BVN->getOperand(I));
6398 }
6399 }
6400
6401 // Nothing to do if there are no EXTRACT_VECTOR_ELTs.
6402 if (!FoundOne)
6403 return SDValue();
6404
6405 // Create the BUILD_VECTOR for the remaining elements, if any.
6406 if (!ResidueOps.empty()) {
6407 while (ResidueOps.size() < NumElements)
6408 ResidueOps.push_back(DAG.getUNDEF(ResidueOps[0].getValueType()));
6409 for (auto &Op : GS.Ops) {
6410 if (!Op.getNode()) {
6411 Op = DAG.getBuildVector(VT, SDLoc(BVN), ResidueOps);
6412 break;
6413 }
6414 }
6415 }
6416 return GS.getNode(DAG, SDLoc(BVN));
6417}
6418
6419bool SystemZTargetLowering::isVectorElementLoad(SDValue Op) const {
6420 if (Op.getOpcode() == ISD::LOAD && cast<LoadSDNode>(Op)->isUnindexed())
6421 return true;
6422 if (auto *AL = dyn_cast<AtomicSDNode>(Op))
6423 if (AL->getOpcode() == ISD::ATOMIC_LOAD)
6424 return true;
6425 if (Subtarget.hasVectorEnhancements2() && Op.getOpcode() == SystemZISD::LRV)
6426 return true;
6427 return false;
6428}
6429
6431 unsigned MergedBits, EVT VT, SDValue Op0,
6432 SDValue Op1) {
6433 MVT IntVecVT = MVT::getVectorVT(MVT::getIntegerVT(MergedBits),
6434 SystemZ::VectorBits / MergedBits);
6435 assert(VT.getSizeInBits() == 128 && IntVecVT.getSizeInBits() == 128 &&
6436 "Handling full vectors only.");
6437 Op0 = DAG.getNode(ISD::BITCAST, DL, IntVecVT, Op0);
6438 Op1 = DAG.getNode(ISD::BITCAST, DL, IntVecVT, Op1);
6439 SDValue Op = DAG.getNode(SystemZISD::MERGE_HIGH, DL, IntVecVT, Op0, Op1);
6440 return DAG.getNode(ISD::BITCAST, DL, VT, Op);
6441}
6442
6444 EVT VT, SmallVectorImpl<SDValue> &Elems,
6445 unsigned Pos) {
6446 SDValue Op01 = buildMergeScalars(DAG, DL, VT, Elems[Pos + 0], Elems[Pos + 1]);
6447 SDValue Op23 = buildMergeScalars(DAG, DL, VT, Elems[Pos + 2], Elems[Pos + 3]);
6448 // Avoid unnecessary undefs by reusing the other operand.
6449 if (Op01.isUndef()) {
6450 if (Op23.isUndef())
6451 return Op01;
6452 Op01 = Op23;
6453 } else if (Op23.isUndef())
6454 Op23 = Op01;
6455 // Merging identical replications is a no-op.
6456 if (Op01.getOpcode() == SystemZISD::REPLICATE && Op01 == Op23)
6457 return Op01;
6458 unsigned MergedBits = VT.getSimpleVT().getScalarSizeInBits() * 2;
6459 return mergeHighParts(DAG, DL, MergedBits, VT, Op01, Op23);
6460}
6461
6462// Combine GPR scalar values Elems into a vector of type VT.
6463SDValue
6464SystemZTargetLowering::buildVector(SelectionDAG &DAG, const SDLoc &DL, EVT VT,
6465 SmallVectorImpl<SDValue> &Elems) const {
6466 // See whether there is a single replicated value.
6468 unsigned int NumElements = Elems.size();
6469 unsigned int Count = 0;
6470 for (auto Elem : Elems) {
6471 if (!Elem.isUndef()) {
6472 if (!Single.getNode())
6473 Single = Elem;
6474 else if (Elem != Single) {
6475 Single = SDValue();
6476 break;
6477 }
6478 Count += 1;
6479 }
6480 }
6481 // There are three cases here:
6482 //
6483 // - if the only defined element is a loaded one, the best sequence
6484 // is a replicating load.
6485 //
6486 // - otherwise, if the only defined element is an i64 value, we will
6487 // end up with the same VLVGP sequence regardless of whether we short-cut
6488 // for replication or fall through to the later code.
6489 //
6490 // - otherwise, if the only defined element is an i32 or smaller value,
6491 // we would need 2 instructions to replicate it: VLVGP followed by VREPx.
6492 // This is only a win if the single defined element is used more than once.
6493 // In other cases we're better off using a single VLVGx.
6494 if (Single.getNode() && (Count > 1 || isVectorElementLoad(Single)))
6495 return DAG.getNode(SystemZISD::REPLICATE, DL, VT, Single);
6496
6497 // If all elements are loads, use VLREP/VLEs (below).
6498 bool AllLoads = true;
6499 for (auto Elem : Elems)
6500 if (!isVectorElementLoad(Elem)) {
6501 AllLoads = false;
6502 break;
6503 }
6504
6505 // The best way of building a v2i64 from two i64s is to use VLVGP.
6506 if (VT == MVT::v2i64 && !AllLoads)
6507 return joinDwords(DAG, DL, Elems[0], Elems[1]);
6508
6509 // Use a 64-bit merge high to combine two doubles.
6510 if (VT == MVT::v2f64 && !AllLoads)
6511 return buildMergeScalars(DAG, DL, VT, Elems[0], Elems[1]);
6512
6513 // Build v4f32 values directly from the FPRs:
6514 //
6515 // <Axxx> <Bxxx> <Cxxxx> <Dxxx>
6516 // V V VMRHF
6517 // <ABxx> <CDxx>
6518 // V VMRHG
6519 // <ABCD>
6520 if (VT == MVT::v4f32 && !AllLoads)
6521 return buildFPVecFromScalars4(DAG, DL, VT, Elems, 0);
6522
6523 // Same for v8f16.
6524 if (VT == MVT::v8f16 && !AllLoads) {
6525 SDValue Op0123 = buildFPVecFromScalars4(DAG, DL, VT, Elems, 0);
6526 SDValue Op4567 = buildFPVecFromScalars4(DAG, DL, VT, Elems, 4);
6527 // Avoid unnecessary undefs by reusing the other operand.
6528 if (Op0123.isUndef())
6529 Op0123 = Op4567;
6530 else if (Op4567.isUndef())
6531 Op4567 = Op0123;
6532 // Merging identical replications is a no-op.
6533 if (Op0123.getOpcode() == SystemZISD::REPLICATE && Op0123 == Op4567)
6534 return Op0123;
6535 return mergeHighParts(DAG, DL, 64, VT, Op0123, Op4567);
6536 }
6537
6538 // Collect the constant terms.
6541
6542 unsigned NumConstants = 0;
6543 for (unsigned I = 0; I < NumElements; ++I) {
6544 SDValue Elem = Elems[I];
6545 if (Elem.getOpcode() == ISD::Constant ||
6546 Elem.getOpcode() == ISD::ConstantFP) {
6547 NumConstants += 1;
6548 Constants[I] = Elem;
6549 Done[I] = true;
6550 }
6551 }
6552 // If there was at least one constant, fill in the other elements of
6553 // Constants with undefs to get a full vector constant and use that
6554 // as the starting point.
6556 SDValue ReplicatedVal;
6557 if (NumConstants > 0) {
6558 for (unsigned I = 0; I < NumElements; ++I)
6559 if (!Constants[I].getNode())
6560 Constants[I] = DAG.getUNDEF(Elems[I].getValueType());
6561 Result = DAG.getBuildVector(VT, DL, Constants);
6562 } else {
6563 // Otherwise try to use VLREP or VLVGP to start the sequence in order to
6564 // avoid a false dependency on any previous contents of the vector
6565 // register.
6566
6567 // Use a VLREP if at least one element is a load. Make sure to replicate
6568 // the load with the most elements having its value.
6569 std::map<const SDNode*, unsigned> UseCounts;
6570 SDNode *LoadMaxUses = nullptr;
6571 for (unsigned I = 0; I < NumElements; ++I)
6572 if (isVectorElementLoad(Elems[I])) {
6573 SDNode *Ld = Elems[I].getNode();
6574 unsigned Count = ++UseCounts[Ld];
6575 if (LoadMaxUses == nullptr || UseCounts[LoadMaxUses] < Count)
6576 LoadMaxUses = Ld;
6577 }
6578 if (LoadMaxUses != nullptr) {
6579 ReplicatedVal = SDValue(LoadMaxUses, 0);
6580 Result = DAG.getNode(SystemZISD::REPLICATE, DL, VT, ReplicatedVal);
6581 } else {
6582 // Try to use VLVGP.
6583 unsigned I1 = NumElements / 2 - 1;
6584 unsigned I2 = NumElements - 1;
6585 bool Def1 = !Elems[I1].isUndef();
6586 bool Def2 = !Elems[I2].isUndef();
6587 if (Def1 || Def2) {
6588 SDValue Elem1 = Elems[Def1 ? I1 : I2];
6589 SDValue Elem2 = Elems[Def2 ? I2 : I1];
6590 Result = DAG.getNode(ISD::BITCAST, DL, VT,
6591 joinDwords(DAG, DL, Elem1, Elem2));
6592 Done[I1] = true;
6593 Done[I2] = true;
6594 } else
6595 Result = DAG.getUNDEF(VT);
6596 }
6597 }
6598
6599 // Use VLVGx to insert the other elements.
6600 for (unsigned I = 0; I < NumElements; ++I)
6601 if (!Done[I] && !Elems[I].isUndef() && Elems[I] != ReplicatedVal)
6602 Result = DAG.getNode(ISD::INSERT_VECTOR_ELT, DL, VT, Result, Elems[I],
6603 DAG.getConstant(I, DL, MVT::i32));
6604 return Result;
6605}
6606
6607SDValue SystemZTargetLowering::lowerBUILD_VECTOR(SDValue Op,
6608 SelectionDAG &DAG) const {
6609 auto *BVN = cast<BuildVectorSDNode>(Op.getNode());
6610 SDLoc DL(Op);
6611 EVT VT = Op.getValueType();
6612
6613 if (BVN->isConstant()) {
6614 if (SystemZVectorConstantInfo(BVN).isVectorConstantLegal(Subtarget))
6615 return Op;
6616
6617 // Fall back to loading it from memory.
6618 return SDValue();
6619 }
6620
6621 // See if we should use shuffles to construct the vector from other vectors.
6622 if (SDValue Res = tryBuildVectorShuffle(DAG, BVN))
6623 return Res;
6624
6625 // Detect SCALAR_TO_VECTOR conversions.
6627 return buildScalarToVector(DAG, DL, VT, Op.getOperand(0));
6628
6629 // Otherwise use buildVector to build the vector up from GPRs.
6630 unsigned NumElements = Op.getNumOperands();
6632 for (unsigned I = 0; I < NumElements; ++I)
6633 Ops[I] = Op.getOperand(I);
6634 return buildVector(DAG, DL, VT, Ops);
6635}
6636
6637SDValue SystemZTargetLowering::lowerVECTOR_SHUFFLE(SDValue Op,
6638 SelectionDAG &DAG) const {
6639 auto *VSN = cast<ShuffleVectorSDNode>(Op.getNode());
6640 SDLoc DL(Op);
6641 EVT VT = Op.getValueType();
6642 unsigned NumElements = VT.getVectorNumElements();
6643
6644 if (VSN->isSplat()) {
6645 SDValue Op0 = Op.getOperand(0);
6646 unsigned Index = VSN->getSplatIndex();
6647 assert(Index < VT.getVectorNumElements() &&
6648 "Splat index should be defined and in first operand");
6649 // See whether the value we're splatting is directly available as a scalar.
6650 if ((Index == 0 && Op0.getOpcode() == ISD::SCALAR_TO_VECTOR) ||
6652 return DAG.getNode(SystemZISD::REPLICATE, DL, VT, Op0.getOperand(Index));
6653 // Otherwise keep it as a vector-to-vector operation.
6654 return DAG.getNode(SystemZISD::SPLAT, DL, VT, Op.getOperand(0),
6655 DAG.getTargetConstant(Index, DL, MVT::i32));
6656 }
6657
6658 GeneralShuffle GS(VT);
6659 for (unsigned I = 0; I < NumElements; ++I) {
6660 int Elt = VSN->getMaskElt(I);
6661 if (Elt < 0)
6662 GS.addUndef();
6663 else if (!GS.add(Op.getOperand(unsigned(Elt) / NumElements),
6664 unsigned(Elt) % NumElements))
6665 return SDValue();
6666 }
6667 return GS.getNode(DAG, SDLoc(VSN));
6668}
6669
6670SDValue SystemZTargetLowering::lowerSCALAR_TO_VECTOR(SDValue Op,
6671 SelectionDAG &DAG) const {
6672 SDLoc DL(Op);
6673 // Just insert the scalar into element 0 of an undefined vector.
6674 return DAG.getNode(ISD::INSERT_VECTOR_ELT, DL,
6675 Op.getValueType(), DAG.getUNDEF(Op.getValueType()),
6676 Op.getOperand(0), DAG.getConstant(0, DL, MVT::i32));
6677}
6678
6679// Shift the lower 2 bytes of Op to the left in order to insert into the
6680// upper 2 bytes of the FP register.
6682 assert(Op.getSimpleValueType() == MVT::i64 &&
6683 "Expexted to convert i64 to f16.");
6684 SDLoc DL(Op);
6685 SDValue Shft = DAG.getNode(ISD::SHL, DL, MVT::i64, Op,
6686 DAG.getConstant(48, DL, MVT::i64));
6687 SDValue BCast = DAG.getNode(ISD::BITCAST, DL, MVT::f64, Shft);
6688 SDValue F16Val =
6689 DAG.getTargetExtractSubreg(SystemZ::subreg_h16, DL, MVT::f16, BCast);
6690 return F16Val;
6691}
6692
6693// Extract Op into GPR and shift the 2 f16 bytes to the right.
6695 assert(Op.getSimpleValueType() == MVT::f16 &&
6696 "Expected to convert f16 to i64.");
6697 SDNode *U32 = DAG.getMachineNode(TargetOpcode::IMPLICIT_DEF, DL, MVT::f64);
6698 SDValue In64 = DAG.getTargetInsertSubreg(SystemZ::subreg_h16, DL, MVT::f64,
6699 SDValue(U32, 0), Op);
6700 SDValue BCast = DAG.getNode(ISD::BITCAST, DL, MVT::i64, In64);
6701 SDValue Shft = DAG.getNode(ISD::SRL, DL, MVT::i64, BCast,
6702 DAG.getConstant(48, DL, MVT::i32));
6703 return Shft;
6704}
6705
6706SDValue SystemZTargetLowering::lowerINSERT_VECTOR_ELT(SDValue Op,
6707 SelectionDAG &DAG) const {
6708 // Handle insertions of floating-point values.
6709 SDLoc DL(Op);
6710 SDValue Op0 = Op.getOperand(0);
6711 SDValue Op1 = Op.getOperand(1);
6712 SDValue Op2 = Op.getOperand(2);
6713 EVT VT = Op.getValueType();
6714
6715 // Insertions into constant indices of a v2f64 can be done using VPDI.
6716 // However, if the inserted value is a bitcast or a constant then it's
6717 // better to use GPRs, as below.
6718 if (VT == MVT::v2f64 &&
6719 Op1.getOpcode() != ISD::BITCAST &&
6720 Op1.getOpcode() != ISD::ConstantFP &&
6721 Op2.getOpcode() == ISD::Constant) {
6722 uint64_t Index = Op2->getAsZExtVal();
6723 unsigned Mask = VT.getVectorNumElements() - 1;
6724 if (Index <= Mask)
6725 return Op;
6726 }
6727
6728 // Otherwise bitcast to the equivalent integer form and insert via a GPR.
6729 MVT IntVT = MVT::getIntegerVT(VT.getScalarSizeInBits());
6730 MVT IntVecVT = MVT::getVectorVT(IntVT, VT.getVectorNumElements());
6731 SDValue IntOp1 =
6732 VT == MVT::v8f16
6733 ? DAG.getZExtOrTrunc(convertFromF16(Op1, DL, DAG), DL, MVT::i32)
6734 : DAG.getNode(ISD::BITCAST, DL, IntVT, Op1);
6735 SDValue Res =
6736 DAG.getNode(ISD::INSERT_VECTOR_ELT, DL, IntVecVT,
6737 DAG.getNode(ISD::BITCAST, DL, IntVecVT, Op0), IntOp1, Op2);
6738 return DAG.getNode(ISD::BITCAST, DL, VT, Res);
6739}
6740
6741SDValue
6742SystemZTargetLowering::lowerEXTRACT_VECTOR_ELT(SDValue Op,
6743 SelectionDAG &DAG) const {
6744 // Handle extractions of floating-point values.
6745 SDLoc DL(Op);
6746 SDValue Op0 = Op.getOperand(0);
6747 SDValue Op1 = Op.getOperand(1);
6748 EVT VT = Op.getValueType();
6749 EVT VecVT = Op0.getValueType();
6750
6751 // Extractions of constant indices can be done directly.
6752 if (auto *CIndexN = dyn_cast<ConstantSDNode>(Op1)) {
6753 uint64_t Index = CIndexN->getZExtValue();
6754 unsigned Mask = VecVT.getVectorNumElements() - 1;
6755 if (Index <= Mask)
6756 return Op;
6757 }
6758
6759 // Otherwise bitcast to the equivalent integer form and extract via a GPR.
6760 MVT IntVT = MVT::getIntegerVT(VT.getSizeInBits());
6761 MVT IntVecVT = MVT::getVectorVT(IntVT, VecVT.getVectorNumElements());
6762 MVT ExtrVT = IntVT == MVT::i16 ? MVT::i32 : IntVT;
6763 SDValue Extr = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, ExtrVT,
6764 DAG.getNode(ISD::BITCAST, DL, IntVecVT, Op0), Op1);
6765 if (VT == MVT::f16)
6766 return convertToF16(DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Extr), DAG);
6767 return DAG.getNode(ISD::BITCAST, DL, VT, Extr);
6768}
6769
6770SDValue SystemZTargetLowering::
6771lowerSIGN_EXTEND_VECTOR_INREG(SDValue Op, SelectionDAG &DAG) const {
6772 SDValue PackedOp = Op.getOperand(0);
6773 EVT OutVT = Op.getValueType();
6774 EVT InVT = PackedOp.getValueType();
6775 unsigned ToBits = OutVT.getScalarSizeInBits();
6776 unsigned FromBits = InVT.getScalarSizeInBits();
6777 unsigned StartOffset = 0;
6778
6779 // If the input is a VECTOR_SHUFFLE, there are a number of important
6780 // cases where we can directly implement the sign-extension of the
6781 // original input lanes of the shuffle.
6782 if (PackedOp.getOpcode() == ISD::VECTOR_SHUFFLE) {
6783 ShuffleVectorSDNode *SVN = cast<ShuffleVectorSDNode>(PackedOp.getNode());
6784 ArrayRef<int> ShuffleMask = SVN->getMask();
6785 int OutNumElts = OutVT.getVectorNumElements();
6786
6787 // Recognize the special case where the sign-extension can be done
6788 // by the VSEG instruction. Handled via the default expander.
6789 if (ToBits == 64 && OutNumElts == 2) {
6790 int NumElem = ToBits / FromBits;
6791 if (ShuffleMask[0] == NumElem - 1 && ShuffleMask[1] == 2 * NumElem - 1)
6792 return SDValue();
6793 }
6794
6795 // Recognize the special case where we can fold the shuffle by
6796 // replacing some of the UNPACK_HIGH with UNPACK_LOW.
6797 int StartOffsetCandidate = -1;
6798 for (int Elt = 0; Elt < OutNumElts; Elt++) {
6799 if (ShuffleMask[Elt] == -1)
6800 continue;
6801 if (ShuffleMask[Elt] % OutNumElts == Elt) {
6802 if (StartOffsetCandidate == -1)
6803 StartOffsetCandidate = ShuffleMask[Elt] - Elt;
6804 if (StartOffsetCandidate == ShuffleMask[Elt] - Elt)
6805 continue;
6806 }
6807 StartOffsetCandidate = -1;
6808 break;
6809 }
6810 if (StartOffsetCandidate != -1) {
6811 StartOffset = StartOffsetCandidate;
6812 PackedOp = PackedOp.getOperand(0);
6813 }
6814 }
6815
6816 do {
6817 FromBits *= 2;
6818 unsigned OutNumElts = SystemZ::VectorBits / FromBits;
6819 EVT OutVT = MVT::getVectorVT(MVT::getIntegerVT(FromBits), OutNumElts);
6820 unsigned Opcode = SystemZISD::UNPACK_HIGH;
6821 if (StartOffset >= OutNumElts) {
6822 Opcode = SystemZISD::UNPACK_LOW;
6823 StartOffset -= OutNumElts;
6824 }
6825 PackedOp = DAG.getNode(Opcode, SDLoc(PackedOp), OutVT, PackedOp);
6826 } while (FromBits != ToBits);
6827 return PackedOp;
6828}
6829
6830// Lower a ZERO_EXTEND_VECTOR_INREG to a vector shuffle with a zero vector.
6831SDValue SystemZTargetLowering::
6832lowerZERO_EXTEND_VECTOR_INREG(SDValue Op, SelectionDAG &DAG) const {
6833 SDValue PackedOp = Op.getOperand(0);
6834 SDLoc DL(Op);
6835 EVT OutVT = Op.getValueType();
6836 EVT InVT = PackedOp.getValueType();
6837 unsigned InNumElts = InVT.getVectorNumElements();
6838 unsigned OutNumElts = OutVT.getVectorNumElements();
6839 unsigned NumInPerOut = InNumElts / OutNumElts;
6840
6841 SDValue ZeroVec =
6842 DAG.getSplatVector(InVT, DL, DAG.getConstant(0, DL, InVT.getScalarType()));
6843
6844 SmallVector<int, 16> Mask(InNumElts);
6845 unsigned ZeroVecElt = InNumElts;
6846 for (unsigned PackedElt = 0; PackedElt < OutNumElts; PackedElt++) {
6847 unsigned MaskElt = PackedElt * NumInPerOut;
6848 unsigned End = MaskElt + NumInPerOut - 1;
6849 for (; MaskElt < End; MaskElt++)
6850 Mask[MaskElt] = ZeroVecElt++;
6851 Mask[MaskElt] = PackedElt;
6852 }
6853 SDValue Shuf = DAG.getVectorShuffle(InVT, DL, PackedOp, ZeroVec, Mask);
6854 return DAG.getNode(ISD::BITCAST, DL, OutVT, Shuf);
6855}
6856
6857SDValue SystemZTargetLowering::lowerShift(SDValue Op, SelectionDAG &DAG,
6858 unsigned ByScalar) const {
6859 // Look for cases where a vector shift can use the *_BY_SCALAR form.
6860 SDValue Op0 = Op.getOperand(0);
6861 SDValue Op1 = Op.getOperand(1);
6862 SDLoc DL(Op);
6863 EVT VT = Op.getValueType();
6864 unsigned ElemBitSize = VT.getScalarSizeInBits();
6865
6866 // See whether the shift vector is a splat represented as BUILD_VECTOR.
6867 if (auto *BVN = dyn_cast<BuildVectorSDNode>(Op1)) {
6868 APInt SplatBits, SplatUndef;
6869 unsigned SplatBitSize;
6870 bool HasAnyUndefs;
6871 // Check for constant splats. Use ElemBitSize as the minimum element
6872 // width and reject splats that need wider elements.
6873 if (BVN->isConstantSplat(SplatBits, SplatUndef, SplatBitSize, HasAnyUndefs,
6874 ElemBitSize, true) &&
6875 SplatBitSize == ElemBitSize) {
6876 SDValue Shift = DAG.getConstant(SplatBits.getZExtValue() & 0xfff,
6877 DL, MVT::i32);
6878 return DAG.getNode(ByScalar, DL, VT, Op0, Shift);
6879 }
6880 // Check for variable splats.
6881 BitVector UndefElements;
6882 SDValue Splat = BVN->getSplatValue(&UndefElements);
6883 if (Splat) {
6884 // Since i32 is the smallest legal type, we either need a no-op
6885 // or a truncation.
6886 SDValue Shift = DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Splat);
6887 return DAG.getNode(ByScalar, DL, VT, Op0, Shift);
6888 }
6889 }
6890
6891 // See whether the shift vector is a splat represented as SHUFFLE_VECTOR,
6892 // and the shift amount is directly available in a GPR.
6893 if (auto *VSN = dyn_cast<ShuffleVectorSDNode>(Op1)) {
6894 if (VSN->isSplat()) {
6895 SDValue VSNOp0 = VSN->getOperand(0);
6896 unsigned Index = VSN->getSplatIndex();
6897 assert(Index < VT.getVectorNumElements() &&
6898 "Splat index should be defined and in first operand");
6899 if ((Index == 0 && VSNOp0.getOpcode() == ISD::SCALAR_TO_VECTOR) ||
6900 VSNOp0.getOpcode() == ISD::BUILD_VECTOR) {
6901 // Since i32 is the smallest legal type, we either need a no-op
6902 // or a truncation.
6903 SDValue Shift = DAG.getNode(ISD::TRUNCATE, DL, MVT::i32,
6904 VSNOp0.getOperand(Index));
6905 return DAG.getNode(ByScalar, DL, VT, Op0, Shift);
6906 }
6907 }
6908 }
6909
6910 // Otherwise just treat the current form as legal.
6911 return Op;
6912}
6913
6914SDValue SystemZTargetLowering::lowerFSHL(SDValue Op, SelectionDAG &DAG) const {
6915 SDLoc DL(Op);
6916
6917 // i128 FSHL with a constant amount that is a multiple of 8 can be
6918 // implemented via VECTOR_SHUFFLE. If we have the vector-enhancements-2
6919 // facility, FSHL with a constant amount less than 8 can be implemented
6920 // via SHL_DOUBLE_BIT, and FSHL with other constant amounts by a
6921 // combination of the two.
6922 if (auto *ShiftAmtNode = dyn_cast<ConstantSDNode>(Op.getOperand(2))) {
6923 uint64_t ShiftAmt = ShiftAmtNode->getZExtValue() & 127;
6924 if ((ShiftAmt & 7) == 0 || Subtarget.hasVectorEnhancements2()) {
6925 SDValue Op0 = DAG.getBitcast(MVT::v16i8, Op.getOperand(0));
6926 SDValue Op1 = DAG.getBitcast(MVT::v16i8, Op.getOperand(1));
6927 if (ShiftAmt > 120) {
6928 // For N in 121..128, fshl N == fshr (128 - N), and for 1 <= N < 8
6929 // SHR_DOUBLE_BIT emits fewer instructions.
6930 SDValue Val =
6931 DAG.getNode(SystemZISD::SHR_DOUBLE_BIT, DL, MVT::v16i8, Op0, Op1,
6932 DAG.getTargetConstant(128 - ShiftAmt, DL, MVT::i32));
6933 return DAG.getBitcast(MVT::i128, Val);
6934 }
6935 SmallVector<int, 16> Mask(16);
6936 for (unsigned Elt = 0; Elt < 16; Elt++)
6937 Mask[Elt] = (ShiftAmt >> 3) + Elt;
6938 SDValue Shuf1 = DAG.getVectorShuffle(MVT::v16i8, DL, Op0, Op1, Mask);
6939 if ((ShiftAmt & 7) == 0)
6940 return DAG.getBitcast(MVT::i128, Shuf1);
6941 SDValue Shuf2 = DAG.getVectorShuffle(MVT::v16i8, DL, Op1, Op1, Mask);
6942 SDValue Val =
6943 DAG.getNode(SystemZISD::SHL_DOUBLE_BIT, DL, MVT::v16i8, Shuf1, Shuf2,
6944 DAG.getTargetConstant(ShiftAmt & 7, DL, MVT::i32));
6945 return DAG.getBitcast(MVT::i128, Val);
6946 }
6947 }
6948
6949 return SDValue();
6950}
6951
6952SDValue SystemZTargetLowering::lowerFSHR(SDValue Op, SelectionDAG &DAG) const {
6953 SDLoc DL(Op);
6954
6955 // i128 FSHR with a constant amount that is a multiple of 8 can be
6956 // implemented via VECTOR_SHUFFLE. If we have the vector-enhancements-2
6957 // facility, FSHR with a constant amount less than 8 can be implemented
6958 // via SHR_DOUBLE_BIT, and FSHR with other constant amounts by a
6959 // combination of the two.
6960 if (auto *ShiftAmtNode = dyn_cast<ConstantSDNode>(Op.getOperand(2))) {
6961 uint64_t ShiftAmt = ShiftAmtNode->getZExtValue() & 127;
6962 if ((ShiftAmt & 7) == 0 || Subtarget.hasVectorEnhancements2()) {
6963 SDValue Op0 = DAG.getBitcast(MVT::v16i8, Op.getOperand(0));
6964 SDValue Op1 = DAG.getBitcast(MVT::v16i8, Op.getOperand(1));
6965 if (ShiftAmt > 120) {
6966 // For N in 121..128, fshr N == fshl (128 - N), and for 1 <= N < 8
6967 // SHL_DOUBLE_BIT emits fewer instructions.
6968 SDValue Val =
6969 DAG.getNode(SystemZISD::SHL_DOUBLE_BIT, DL, MVT::v16i8, Op0, Op1,
6970 DAG.getTargetConstant(128 - ShiftAmt, DL, MVT::i32));
6971 return DAG.getBitcast(MVT::i128, Val);
6972 }
6973 SmallVector<int, 16> Mask(16);
6974 for (unsigned Elt = 0; Elt < 16; Elt++)
6975 Mask[Elt] = 16 - (ShiftAmt >> 3) + Elt;
6976 SDValue Shuf1 = DAG.getVectorShuffle(MVT::v16i8, DL, Op0, Op1, Mask);
6977 if ((ShiftAmt & 7) == 0)
6978 return DAG.getBitcast(MVT::i128, Shuf1);
6979 SDValue Shuf2 = DAG.getVectorShuffle(MVT::v16i8, DL, Op0, Op0, Mask);
6980 SDValue Val =
6981 DAG.getNode(SystemZISD::SHR_DOUBLE_BIT, DL, MVT::v16i8, Shuf2, Shuf1,
6982 DAG.getTargetConstant(ShiftAmt & 7, DL, MVT::i32));
6983 return DAG.getBitcast(MVT::i128, Val);
6984 }
6985 }
6986
6987 return SDValue();
6988}
6989
6991 SDLoc DL(Op);
6992 SDValue Src = Op.getOperand(0);
6993 MVT DstVT = Op.getSimpleValueType();
6994
6996 unsigned SrcAS = N->getSrcAddressSpace();
6997
6998 assert(SrcAS != N->getDestAddressSpace() &&
6999 "addrspacecast must be between different address spaces");
7000
7001 // addrspacecast [0 <- 1] : Assinging a ptr32 value to a 64-bit pointer.
7002 // addrspacecast [1 <- 0] : Assigining a 64-bit pointer to a ptr32 value.
7003 if (SrcAS == SYSTEMZAS::PTR32 && DstVT == MVT::i64) {
7004 Op = DAG.getNode(ISD::AND, DL, MVT::i32, Src,
7005 DAG.getConstant(0x7fffffff, DL, MVT::i32));
7006 Op = DAG.getNode(ISD::ZERO_EXTEND, DL, DstVT, Op);
7007 } else if (DstVT == MVT::i32) {
7008 Op = DAG.getNode(ISD::TRUNCATE, DL, DstVT, Src);
7009 Op = DAG.getNode(ISD::AND, DL, MVT::i32, Op,
7010 DAG.getConstant(0x7fffffff, DL, MVT::i32));
7011 Op = DAG.getNode(ISD::ZERO_EXTEND, DL, DstVT, Op);
7012 } else {
7013 report_fatal_error("Bad address space in addrspacecast");
7014 }
7015 return Op;
7016}
7017
7018SDValue SystemZTargetLowering::lowerFP_EXTEND(SDValue Op,
7019 SelectionDAG &DAG) const {
7020 SDValue In = Op.getOperand(Op->isStrictFPOpcode() ? 1 : 0);
7021 if (In.getSimpleValueType() != MVT::f16)
7022 return Op; // Legal
7023 return SDValue(); // Let legalizer emit the libcall.
7024}
7025
7027 MVT VT, SDValue Arg, SDLoc DL,
7028 SDValue Chain, bool IsStrict) const {
7029 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpected request for libcall!");
7030 MakeLibCallOptions CallOptions;
7031 SDValue Result;
7032 std::tie(Result, Chain) =
7033 makeLibCall(DAG, LC, VT, Arg, CallOptions, DL, Chain);
7034 return IsStrict ? DAG.getMergeValues({Result, Chain}, DL) : Result;
7035}
7036
7037SDValue SystemZTargetLowering::lower_FP_TO_INT(SDValue Op,
7038 SelectionDAG &DAG) const {
7039 bool IsSigned = (Op->getOpcode() == ISD::FP_TO_SINT ||
7040 Op->getOpcode() == ISD::STRICT_FP_TO_SINT);
7041 bool IsStrict = Op->isStrictFPOpcode();
7042 SDLoc DL(Op);
7043 MVT VT = Op.getSimpleValueType();
7044 SDValue InOp = Op.getOperand(IsStrict ? 1 : 0);
7045 SDValue Chain = IsStrict ? Op.getOperand(0) : DAG.getEntryNode();
7046 EVT InVT = InOp.getValueType();
7047
7048 // FP to unsigned is not directly supported on z10. Promoting an i32
7049 // result to (signed) i64 doesn't generate an inexact condition (fp
7050 // exception) for values that are outside the i32 range but in the i64
7051 // range, so use the default expansion.
7052 if (!Subtarget.hasFPExtension() && !IsSigned)
7053 // Expand i32/i64. F16 values will be recognized to fit and extended.
7054 return SDValue();
7055
7056 // Conversion from f16 is done via f32.
7057 if (InOp.getSimpleValueType() == MVT::f16) {
7059 LowerOperationWrapper(Op.getNode(), Results, DAG);
7060 return DAG.getMergeValues(Results, DL);
7061 }
7062
7063 if (VT == MVT::i128) {
7064 RTLIB::Libcall LC =
7065 IsSigned ? RTLIB::getFPTOSINT(InVT, VT) : RTLIB::getFPTOUINT(InVT, VT);
7066 return useLibCall(DAG, LC, VT, InOp, DL, Chain, IsStrict);
7067 }
7068
7069 return Op; // Legal
7070}
7071
7072SDValue SystemZTargetLowering::lower_INT_TO_FP(SDValue Op,
7073 SelectionDAG &DAG) const {
7074 bool IsSigned = (Op->getOpcode() == ISD::SINT_TO_FP ||
7075 Op->getOpcode() == ISD::STRICT_SINT_TO_FP);
7076 bool IsStrict = Op->isStrictFPOpcode();
7077 SDLoc DL(Op);
7078 MVT VT = Op.getSimpleValueType();
7079 SDValue InOp = Op.getOperand(IsStrict ? 1 : 0);
7080 SDValue Chain = IsStrict ? Op.getOperand(0) : DAG.getEntryNode();
7081 EVT InVT = InOp.getValueType();
7082
7083 // Conversion to f16 is done via f32.
7084 if (VT == MVT::f16) {
7086 LowerOperationWrapper(Op.getNode(), Results, DAG);
7087 return DAG.getMergeValues(Results, DL);
7088 }
7089
7090 // Unsigned to fp is not directly supported on z10.
7091 if (!Subtarget.hasFPExtension() && !IsSigned)
7092 return SDValue(); // Expand i64.
7093
7094 if (InVT == MVT::i128) {
7095 RTLIB::Libcall LC =
7096 IsSigned ? RTLIB::getSINTTOFP(InVT, VT) : RTLIB::getUINTTOFP(InVT, VT);
7097 return useLibCall(DAG, LC, VT, InOp, DL, Chain, IsStrict);
7098 }
7099
7100 return Op; // Legal
7101}
7102
7103// Lower an f16 LOAD in case of no vector support.
7104SDValue SystemZTargetLowering::lowerLoadF16(SDValue Op,
7105 SelectionDAG &DAG) const {
7106 EVT RegVT = Op.getValueType();
7107 assert(RegVT == MVT::f16 && "Expected to lower an f16 load.");
7108 (void)RegVT;
7109
7110 // Load as integer.
7111 SDLoc DL(Op);
7112 SDValue NewLd;
7113 if (auto *AtomicLd = dyn_cast<AtomicSDNode>(Op.getNode())) {
7114 assert(EVT(RegVT) == AtomicLd->getMemoryVT() && "Unhandled f16 load");
7115 NewLd = DAG.getAtomicLoad(ISD::EXTLOAD, DL, MVT::i16, MVT::i64,
7116 AtomicLd->getChain(), AtomicLd->getBasePtr(),
7117 AtomicLd->getMemOperand());
7118 } else {
7119 LoadSDNode *Ld = cast<LoadSDNode>(Op.getNode());
7120 assert(EVT(RegVT) == Ld->getMemoryVT() && "Unhandled f16 load");
7121 NewLd = DAG.getExtLoad(ISD::EXTLOAD, DL, MVT::i64, Ld->getChain(),
7122 Ld->getBasePtr(), Ld->getPointerInfo(), MVT::i16,
7123 Ld->getBaseAlign(), Ld->getMemOperand()->getFlags());
7124 }
7125 SDValue F16Val = convertToF16(NewLd, DAG);
7126 return DAG.getMergeValues({F16Val, NewLd.getValue(1)}, DL);
7127}
7128
7129// Lower an f16 STORE in case of no vector support.
7130SDValue SystemZTargetLowering::lowerStoreF16(SDValue Op,
7131 SelectionDAG &DAG) const {
7132 SDLoc DL(Op);
7133 SDValue Shft = convertFromF16(Op->getOperand(1), DL, DAG);
7134
7135 if (auto *AtomicSt = dyn_cast<AtomicSDNode>(Op.getNode()))
7136 return DAG.getAtomic(ISD::ATOMIC_STORE, DL, MVT::i16, AtomicSt->getChain(),
7137 Shft, AtomicSt->getBasePtr(),
7138 AtomicSt->getMemOperand());
7139
7140 StoreSDNode *St = cast<StoreSDNode>(Op.getNode());
7141 return DAG.getTruncStore(St->getChain(), DL, Shft, St->getBasePtr(), MVT::i16,
7142 St->getMemOperand());
7143}
7144
7145SDValue SystemZTargetLowering::lowerIS_FPCLASS(SDValue Op,
7146 SelectionDAG &DAG) const {
7147 SDLoc DL(Op);
7148 MVT ResultVT = Op.getSimpleValueType();
7149 SDValue Arg = Op.getOperand(0);
7150 unsigned Check = Op.getConstantOperandVal(1);
7151
7152 unsigned TDCMask = 0;
7153 if (Check & fcSNan)
7155 if (Check & fcQNan)
7157 if (Check & fcPosInf)
7159 if (Check & fcNegInf)
7161 if (Check & fcPosNormal)
7163 if (Check & fcNegNormal)
7165 if (Check & fcPosSubnormal)
7167 if (Check & fcNegSubnormal)
7169 if (Check & fcPosZero)
7170 TDCMask |= SystemZ::TDCMASK_ZERO_PLUS;
7171 if (Check & fcNegZero)
7172 TDCMask |= SystemZ::TDCMASK_ZERO_MINUS;
7173 SDValue TDCMaskV = DAG.getConstant(TDCMask, DL, MVT::i64);
7174
7175 SDValue Intr = DAG.getNode(SystemZISD::TDC, DL, ResultVT, Arg, TDCMaskV);
7176 return getCCResult(DAG, Intr);
7177}
7178
7179SDValue SystemZTargetLowering::lowerREADCYCLECOUNTER(SDValue Op,
7180 SelectionDAG &DAG) const {
7181 SDLoc DL(Op);
7182 SDValue Chain = Op.getOperand(0);
7183
7184 // STCKF only supports a memory operand, so we have to use a temporary.
7185 SDValue StackPtr = DAG.CreateStackTemporary(MVT::i64);
7186 int SPFI = cast<FrameIndexSDNode>(StackPtr.getNode())->getIndex();
7187 MachinePointerInfo MPI =
7189
7190 // Use STCFK to store the TOD clock into the temporary.
7191 SDValue StoreOps[] = {Chain, StackPtr};
7192 Chain = DAG.getMemIntrinsicNode(
7193 SystemZISD::STCKF, DL, DAG.getVTList(MVT::Other), StoreOps, MVT::i64,
7194 MPI, MaybeAlign(), MachineMemOperand::MOStore);
7195
7196 // And read it back from there.
7197 return DAG.getLoad(MVT::i64, DL, Chain, StackPtr, MPI);
7198}
7199
7201 SelectionDAG &DAG) const {
7202 switch (Op.getOpcode()) {
7203 case ISD::FRAMEADDR:
7204 return lowerFRAMEADDR(Op, DAG);
7205 case ISD::RETURNADDR:
7206 return lowerRETURNADDR(Op, DAG);
7207 case ISD::BR_CC:
7208 return lowerBR_CC(Op, DAG);
7209 case ISD::SELECT_CC:
7210 return lowerSELECT_CC(Op, DAG);
7211 case ISD::SETCC:
7212 return lowerSETCC(Op, DAG);
7213 case ISD::STRICT_FSETCC:
7214 return lowerSTRICT_FSETCC(Op, DAG, false);
7216 return lowerSTRICT_FSETCC(Op, DAG, true);
7217 case ISD::GlobalAddress:
7218 return lowerGlobalAddress(cast<GlobalAddressSDNode>(Op), DAG);
7220 return lowerGlobalTLSAddress(cast<GlobalAddressSDNode>(Op), DAG);
7221 case ISD::BlockAddress:
7222 return lowerBlockAddress(cast<BlockAddressSDNode>(Op), DAG);
7223 case ISD::JumpTable:
7224 return lowerJumpTable(cast<JumpTableSDNode>(Op), DAG);
7225 case ISD::ConstantPool:
7226 return lowerConstantPool(cast<ConstantPoolSDNode>(Op), DAG);
7227 case ISD::BITCAST:
7228 return lowerBITCAST(Op, DAG);
7229 case ISD::VASTART:
7230 return lowerVASTART(Op, DAG);
7231 case ISD::VACOPY:
7232 return lowerVACOPY(Op, DAG);
7234 return lowerDYNAMIC_STACKALLOC(Op, DAG);
7236 return lowerGET_DYNAMIC_AREA_OFFSET(Op, DAG);
7237 case ISD::MULHS:
7238 return lowerMULH(Op, DAG, SystemZISD::SMUL_LOHI);
7239 case ISD::MULHU:
7240 return lowerMULH(Op, DAG, SystemZISD::UMUL_LOHI);
7241 case ISD::SMUL_LOHI:
7242 return lowerSMUL_LOHI(Op, DAG);
7243 case ISD::UMUL_LOHI:
7244 return lowerUMUL_LOHI(Op, DAG);
7245 case ISD::SDIVREM:
7246 return lowerSDIVREM(Op, DAG);
7247 case ISD::UDIVREM:
7248 return lowerUDIVREM(Op, DAG);
7249 case ISD::SADDO:
7250 case ISD::SSUBO:
7251 case ISD::UADDO:
7252 case ISD::USUBO:
7253 return lowerXALUO(Op, DAG);
7254 case ISD::UADDO_CARRY:
7255 case ISD::USUBO_CARRY:
7256 return lowerUADDSUBO_CARRY(Op, DAG);
7257 case ISD::OR:
7258 return lowerOR(Op, DAG);
7259 case ISD::CTPOP:
7260 return lowerCTPOP(Op, DAG);
7261 case ISD::VECREDUCE_ADD:
7262 return lowerVECREDUCE_ADD(Op, DAG);
7263 case ISD::ATOMIC_FENCE:
7264 return lowerATOMIC_FENCE(Op, DAG);
7265 case ISD::ATOMIC_SWAP:
7266 return lowerATOMIC_LOAD_OP(Op, DAG, SystemZISD::ATOMIC_SWAPW);
7267 case ISD::ATOMIC_STORE:
7268 return lowerATOMIC_STORE(Op, DAG);
7269 case ISD::ATOMIC_LOAD:
7270 return lowerATOMIC_LOAD(Op, DAG);
7272 return lowerATOMIC_LOAD_OP(Op, DAG, SystemZISD::ATOMIC_LOADW_ADD);
7274 return lowerATOMIC_LOAD_SUB(Op, DAG);
7276 return lowerATOMIC_LOAD_OP(Op, DAG, SystemZISD::ATOMIC_LOADW_AND);
7278 return lowerATOMIC_LOAD_OP(Op, DAG, SystemZISD::ATOMIC_LOADW_OR);
7280 return lowerATOMIC_LOAD_OP(Op, DAG, SystemZISD::ATOMIC_LOADW_XOR);
7282 return lowerATOMIC_LOAD_OP(Op, DAG, SystemZISD::ATOMIC_LOADW_NAND);
7284 return lowerATOMIC_LOAD_OP(Op, DAG, SystemZISD::ATOMIC_LOADW_MIN);
7286 return lowerATOMIC_LOAD_OP(Op, DAG, SystemZISD::ATOMIC_LOADW_MAX);
7288 return lowerATOMIC_LOAD_OP(Op, DAG, SystemZISD::ATOMIC_LOADW_UMIN);
7290 return lowerATOMIC_LOAD_OP(Op, DAG, SystemZISD::ATOMIC_LOADW_UMAX);
7292 return lowerATOMIC_CMP_SWAP(Op, DAG);
7293 case ISD::STACKSAVE:
7294 return lowerSTACKSAVE(Op, DAG);
7295 case ISD::STACKRESTORE:
7296 return lowerSTACKRESTORE(Op, DAG);
7297 case ISD::PREFETCH:
7298 return lowerPREFETCH(Op, DAG);
7300 return lowerINTRINSIC_W_CHAIN(Op, DAG);
7302 return lowerINTRINSIC_WO_CHAIN(Op, DAG);
7303 case ISD::BUILD_VECTOR:
7304 return lowerBUILD_VECTOR(Op, DAG);
7306 return lowerVECTOR_SHUFFLE(Op, DAG);
7308 return lowerSCALAR_TO_VECTOR(Op, DAG);
7310 return lowerINSERT_VECTOR_ELT(Op, DAG);
7312 return lowerEXTRACT_VECTOR_ELT(Op, DAG);
7314 return lowerSIGN_EXTEND_VECTOR_INREG(Op, DAG);
7316 return lowerZERO_EXTEND_VECTOR_INREG(Op, DAG);
7317 case ISD::SHL:
7318 return lowerShift(Op, DAG, SystemZISD::VSHL_BY_SCALAR);
7319 case ISD::SRL:
7320 return lowerShift(Op, DAG, SystemZISD::VSRL_BY_SCALAR);
7321 case ISD::SRA:
7322 return lowerShift(Op, DAG, SystemZISD::VSRA_BY_SCALAR);
7323 case ISD::ADDRSPACECAST:
7324 return lowerAddrSpaceCast(Op, DAG);
7325 case ISD::ROTL:
7326 return lowerShift(Op, DAG, SystemZISD::VROTL_BY_SCALAR);
7327 case ISD::FSHL:
7328 return lowerFSHL(Op, DAG);
7329 case ISD::FSHR:
7330 return lowerFSHR(Op, DAG);
7331 case ISD::FP_EXTEND:
7333 return lowerFP_EXTEND(Op, DAG);
7334 case ISD::FP_TO_UINT:
7335 case ISD::FP_TO_SINT:
7338 return lower_FP_TO_INT(Op, DAG);
7339 case ISD::UINT_TO_FP:
7340 case ISD::SINT_TO_FP:
7343 return lower_INT_TO_FP(Op, DAG);
7344 case ISD::LOAD:
7345 return lowerLoadF16(Op, DAG);
7346 case ISD::STORE:
7347 return lowerStoreF16(Op, DAG);
7348 case ISD::IS_FPCLASS:
7349 return lowerIS_FPCLASS(Op, DAG);
7350 case ISD::GET_ROUNDING:
7351 return lowerGET_ROUNDING(Op, DAG);
7353 return lowerREADCYCLECOUNTER(Op, DAG);
7356 // These operations are legal on our platform, but we cannot actually
7357 // set the operation action to Legal as common code would treat this
7358 // as equivalent to Expand. Instead, we keep the operation action to
7359 // Custom and just leave them unchanged here.
7360 return Op;
7361
7362 default:
7363 llvm_unreachable("Unexpected node to lower");
7364 }
7365}
7366
7368 const SDLoc &SL) {
7369 // If i128 is legal, just use a normal bitcast.
7370 if (DAG.getTargetLoweringInfo().isTypeLegal(MVT::i128))
7371 return DAG.getBitcast(MVT::f128, Src);
7372
7373 // Otherwise, f128 must live in FP128, so do a partwise move.
7375 &SystemZ::FP128BitRegClass);
7376
7377 SDValue Hi, Lo;
7378 std::tie(Lo, Hi) = DAG.SplitScalar(Src, SL, MVT::i64, MVT::i64);
7379
7380 Hi = DAG.getBitcast(MVT::f64, Hi);
7381 Lo = DAG.getBitcast(MVT::f64, Lo);
7382
7383 SDNode *Pair = DAG.getMachineNode(
7384 SystemZ::REG_SEQUENCE, SL, MVT::f128,
7385 {DAG.getTargetConstant(SystemZ::FP128BitRegClassID, SL, MVT::i32), Lo,
7386 DAG.getTargetConstant(SystemZ::subreg_l64, SL, MVT::i32), Hi,
7387 DAG.getTargetConstant(SystemZ::subreg_h64, SL, MVT::i32)});
7388 return SDValue(Pair, 0);
7389}
7390
7392 const SDLoc &SL) {
7393 // If i128 is legal, just use a normal bitcast.
7394 if (DAG.getTargetLoweringInfo().isTypeLegal(MVT::i128))
7395 return DAG.getBitcast(MVT::i128, Src);
7396
7397 // Otherwise, f128 must live in FP128, so do a partwise move.
7399 &SystemZ::FP128BitRegClass);
7400
7401 SDValue LoFP =
7402 DAG.getTargetExtractSubreg(SystemZ::subreg_l64, SL, MVT::f64, Src);
7403 SDValue HiFP =
7404 DAG.getTargetExtractSubreg(SystemZ::subreg_h64, SL, MVT::f64, Src);
7405 SDValue Lo = DAG.getNode(ISD::BITCAST, SL, MVT::i64, LoFP);
7406 SDValue Hi = DAG.getNode(ISD::BITCAST, SL, MVT::i64, HiFP);
7407
7408 return DAG.getNode(ISD::BUILD_PAIR, SL, MVT::i128, Lo, Hi);
7409}
7410
7411// Lower operations with invalid operand or result types.
7412void
7415 SelectionDAG &DAG) const {
7416 switch (N->getOpcode()) {
7417 case ISD::ATOMIC_LOAD: {
7418 SDLoc DL(N);
7419 SDVTList Tys = DAG.getVTList(MVT::Untyped, MVT::Other);
7420 SDValue Ops[] = { N->getOperand(0), N->getOperand(1) };
7421 MachineMemOperand *MMO = cast<AtomicSDNode>(N)->getMemOperand();
7422 SDValue Res = DAG.getMemIntrinsicNode(SystemZISD::ATOMIC_LOAD_128,
7423 DL, Tys, Ops, MVT::i128, MMO);
7424
7425 SDValue Lowered = lowerGR128ToI128(DAG, Res);
7426 if (N->getValueType(0) == MVT::f128)
7427 Lowered = expandBitCastI128ToF128(DAG, Lowered, DL);
7428 Results.push_back(Lowered);
7429 Results.push_back(Res.getValue(1));
7430 break;
7431 }
7432 case ISD::ATOMIC_STORE: {
7433 SDLoc DL(N);
7434 SDVTList Tys = DAG.getVTList(MVT::Other);
7435 SDValue Val = N->getOperand(1);
7436 if (Val.getValueType() == MVT::f128)
7437 Val = expandBitCastF128ToI128(DAG, Val, DL);
7438 Val = lowerI128ToGR128(DAG, Val);
7439
7440 SDValue Ops[] = {N->getOperand(0), Val, N->getOperand(2)};
7441 MachineMemOperand *MMO = cast<AtomicSDNode>(N)->getMemOperand();
7442 SDValue Res = DAG.getMemIntrinsicNode(SystemZISD::ATOMIC_STORE_128,
7443 DL, Tys, Ops, MVT::i128, MMO);
7444 // We have to enforce sequential consistency by performing a
7445 // serialization operation after the store.
7446 if (cast<AtomicSDNode>(N)->getSuccessOrdering() ==
7448 Res = SDValue(DAG.getMachineNode(SystemZ::Serialize, DL,
7449 MVT::Other, Res), 0);
7450 Results.push_back(Res);
7451 break;
7452 }
7454 SDLoc DL(N);
7455 SDVTList Tys = DAG.getVTList(MVT::Untyped, MVT::i32, MVT::Other);
7456 SDValue Ops[] = { N->getOperand(0), N->getOperand(1),
7457 lowerI128ToGR128(DAG, N->getOperand(2)),
7458 lowerI128ToGR128(DAG, N->getOperand(3)) };
7459 MachineMemOperand *MMO = cast<AtomicSDNode>(N)->getMemOperand();
7460 SDValue Res = DAG.getMemIntrinsicNode(SystemZISD::ATOMIC_CMP_SWAP_128,
7461 DL, Tys, Ops, MVT::i128, MMO);
7462 SDValue Success = emitSETCC(DAG, DL, Res.getValue(1),
7464 Success = DAG.getZExtOrTrunc(Success, DL, N->getValueType(1));
7465 Results.push_back(lowerGR128ToI128(DAG, Res));
7466 Results.push_back(Success);
7467 Results.push_back(Res.getValue(2));
7468 break;
7469 }
7470 case ISD::BITCAST: {
7471 if (useSoftFloat())
7472 return;
7473 SDLoc DL(N);
7474 SDValue Src = N->getOperand(0);
7475 EVT SrcVT = Src.getValueType();
7476 EVT ResVT = N->getValueType(0);
7477 if (ResVT == MVT::i128 && SrcVT == MVT::f128)
7478 Results.push_back(expandBitCastF128ToI128(DAG, Src, DL));
7479 else if (SrcVT == MVT::i16 && ResVT == MVT::f16) {
7480 if (Subtarget.hasVector()) {
7481 SDValue In32 = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i32, Src);
7482 Results.push_back(SDValue(
7483 DAG.getMachineNode(SystemZ::LEFR_16, DL, MVT::f16, In32), 0));
7484 } else {
7485 SDValue In64 = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Src);
7486 Results.push_back(convertToF16(In64, DAG));
7487 }
7488 } else if (SrcVT == MVT::f16 && ResVT == MVT::i16) {
7489 SDValue ExtractedVal =
7490 Subtarget.hasVector()
7491 ? SDValue(DAG.getMachineNode(SystemZ::LFER_16, DL, MVT::i32, Src),
7492 0)
7493 : convertFromF16(Src, DL, DAG);
7494 Results.push_back(DAG.getZExtOrTrunc(ExtractedVal, DL, ResVT));
7495 }
7496 break;
7497 }
7498 case ISD::UINT_TO_FP:
7499 case ISD::SINT_TO_FP:
7502 if (useSoftFloat())
7503 return;
7504 bool IsStrict = N->isStrictFPOpcode();
7505 SDLoc DL(N);
7506 SDValue InOp = N->getOperand(IsStrict ? 1 : 0);
7507 EVT ResVT = N->getValueType(0);
7508 SDValue Chain = IsStrict ? N->getOperand(0) : DAG.getEntryNode();
7509 if (ResVT == MVT::f16) {
7510 if (!IsStrict) {
7511 SDValue OpF32 = DAG.getNode(N->getOpcode(), DL, MVT::f32, InOp);
7512 Results.push_back(DAG.getFPExtendOrRound(OpF32, DL, MVT::f16));
7513 } else {
7514 SDValue OpF32 =
7515 DAG.getNode(N->getOpcode(), DL, DAG.getVTList(MVT::f32, MVT::Other),
7516 {Chain, InOp});
7517 SDValue F16Res;
7518 std::tie(F16Res, Chain) = DAG.getStrictFPExtendOrRound(
7519 OpF32, OpF32.getValue(1), DL, MVT::f16);
7520 Results.push_back(F16Res);
7521 Results.push_back(Chain);
7522 }
7523 }
7524 break;
7525 }
7526 case ISD::FP_TO_UINT:
7527 case ISD::FP_TO_SINT:
7530 if (useSoftFloat())
7531 return;
7532 bool IsStrict = N->isStrictFPOpcode();
7533 SDLoc DL(N);
7534 EVT ResVT = N->getValueType(0);
7535 SDValue InOp = N->getOperand(IsStrict ? 1 : 0);
7536 EVT InVT = InOp->getValueType(0);
7537 SDValue Chain = IsStrict ? N->getOperand(0) : DAG.getEntryNode();
7538 if (InVT == MVT::f16) {
7539 if (!IsStrict) {
7540 SDValue InF32 = DAG.getFPExtendOrRound(InOp, DL, MVT::f32);
7541 Results.push_back(DAG.getNode(N->getOpcode(), DL, ResVT, InF32));
7542 } else {
7543 SDValue InF32;
7544 std::tie(InF32, Chain) =
7545 DAG.getStrictFPExtendOrRound(InOp, Chain, DL, MVT::f32);
7546 SDValue OpF32 =
7547 DAG.getNode(N->getOpcode(), DL, DAG.getVTList(ResVT, MVT::Other),
7548 {Chain, InF32});
7549 Results.push_back(OpF32);
7550 Results.push_back(OpF32.getValue(1));
7551 }
7552 }
7553 break;
7554 }
7555 default:
7556 llvm_unreachable("Unexpected node to lower");
7557 }
7558}
7559
7560void
7566
7567// Return true if VT is a vector whose elements are a whole number of bytes
7568// in width. Also check for presence of vector support.
7569bool SystemZTargetLowering::canTreatAsByteVector(EVT VT) const {
7570 if (!Subtarget.hasVector())
7571 return false;
7572
7573 return VT.isVector() && VT.getScalarSizeInBits() % 8 == 0 && VT.isSimple();
7574}
7575
7576// Try to simplify an EXTRACT_VECTOR_ELT from a vector of type VecVT
7577// producing a result of type ResVT. Op is a possibly bitcast version
7578// of the input vector and Index is the index (based on type VecVT) that
7579// should be extracted. Return the new extraction if a simplification
7580// was possible or if Force is true.
7581SDValue SystemZTargetLowering::combineExtract(const SDLoc &DL, EVT ResVT,
7582 EVT VecVT, SDValue Op,
7583 unsigned Index,
7584 DAGCombinerInfo &DCI,
7585 bool Force) const {
7586 SelectionDAG &DAG = DCI.DAG;
7587
7588 // The number of bytes being extracted.
7589 unsigned BytesPerElement = VecVT.getVectorElementType().getStoreSize();
7590
7591 for (;;) {
7592 unsigned Opcode = Op.getOpcode();
7593 if (Opcode == ISD::BITCAST)
7594 // Look through bitcasts.
7595 Op = Op.getOperand(0);
7596 else if ((Opcode == ISD::VECTOR_SHUFFLE || Opcode == SystemZISD::SPLAT) &&
7597 canTreatAsByteVector(Op.getValueType())) {
7598 // Get a VPERM-like permute mask and see whether the bytes covered
7599 // by the extracted element are a contiguous sequence from one
7600 // source operand.
7602 if (!getVPermMask(Op, Bytes))
7603 break;
7604 int First;
7605 if (!getShuffleInput(Bytes, Index * BytesPerElement,
7606 BytesPerElement, First))
7607 break;
7608 if (First < 0)
7609 return DAG.getUNDEF(ResVT);
7610 // Make sure the contiguous sequence starts at a multiple of the
7611 // original element size.
7612 unsigned Byte = unsigned(First) % Bytes.size();
7613 if (Byte % BytesPerElement != 0)
7614 break;
7615 // We can get the extracted value directly from an input.
7616 Index = Byte / BytesPerElement;
7617 Op = Op.getOperand(unsigned(First) / Bytes.size());
7618 Force = true;
7619 } else if (Opcode == ISD::BUILD_VECTOR &&
7620 canTreatAsByteVector(Op.getValueType())) {
7621 // We can only optimize this case if the BUILD_VECTOR elements are
7622 // at least as wide as the extracted value.
7623 EVT OpVT = Op.getValueType();
7624 unsigned OpBytesPerElement = OpVT.getVectorElementType().getStoreSize();
7625 if (OpBytesPerElement < BytesPerElement)
7626 break;
7627 // Make sure that the least-significant bit of the extracted value
7628 // is the least significant bit of an input.
7629 unsigned End = (Index + 1) * BytesPerElement;
7630 if (End % OpBytesPerElement != 0)
7631 break;
7632 // We're extracting the low part of one operand of the BUILD_VECTOR.
7633 Op = Op.getOperand(End / OpBytesPerElement - 1);
7634 EVT ResIntVT = MVT::getIntegerVT(ResVT.getSizeInBits());
7635 if (!isTypeLegal(ResIntVT))
7636 break;
7637 if (!Op.getValueType().isInteger()) {
7638 EVT OpIntVT = MVT::getIntegerVT(Op.getValueSizeInBits());
7639 if (!isTypeLegal(OpIntVT))
7640 break;
7641 Op = DAG.getNode(ISD::BITCAST, DL, OpIntVT, Op);
7642 DCI.AddToWorklist(Op.getNode());
7643 }
7644 Op = DAG.getNode(ISD::TRUNCATE, DL, ResIntVT, Op);
7645 if (ResIntVT != ResVT) {
7646 DCI.AddToWorklist(Op.getNode());
7647 Op = DAG.getNode(ISD::BITCAST, DL, ResVT, Op);
7648 }
7649 return Op;
7650 } else if ((Opcode == ISD::SIGN_EXTEND_VECTOR_INREG ||
7652 Opcode == ISD::ANY_EXTEND_VECTOR_INREG) &&
7653 canTreatAsByteVector(Op.getValueType()) &&
7654 canTreatAsByteVector(Op.getOperand(0).getValueType())) {
7655 // Make sure that only the unextended bits are significant.
7656 EVT ExtVT = Op.getValueType();
7657 EVT OpVT = Op.getOperand(0).getValueType();
7658 unsigned ExtBytesPerElement = ExtVT.getVectorElementType().getStoreSize();
7659 unsigned OpBytesPerElement = OpVT.getVectorElementType().getStoreSize();
7660 unsigned Byte = Index * BytesPerElement;
7661 unsigned SubByte = Byte % ExtBytesPerElement;
7662 unsigned MinSubByte = ExtBytesPerElement - OpBytesPerElement;
7663 if (SubByte < MinSubByte ||
7664 SubByte + BytesPerElement > ExtBytesPerElement)
7665 break;
7666 // Get the byte offset of the unextended element
7667 Byte = Byte / ExtBytesPerElement * OpBytesPerElement;
7668 // ...then add the byte offset relative to that element.
7669 Byte += SubByte - MinSubByte;
7670 if (Byte % BytesPerElement != 0)
7671 break;
7672 Op = Op.getOperand(0);
7673 Index = Byte / BytesPerElement;
7674 Force = true;
7675 } else
7676 break;
7677 }
7678 if (Force) {
7679 if (Op.getValueType() != VecVT) {
7680 Op = DAG.getNode(ISD::BITCAST, DL, VecVT, Op);
7681 DCI.AddToWorklist(Op.getNode());
7682 }
7683 return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, ResVT, Op,
7684 DAG.getConstant(Index, DL, MVT::i32));
7685 }
7686 return SDValue();
7687}
7688
7689// Optimize vector operations in scalar value Op on the basis that Op
7690// is truncated to TruncVT.
7691SDValue SystemZTargetLowering::combineTruncateExtract(
7692 const SDLoc &DL, EVT TruncVT, SDValue Op, DAGCombinerInfo &DCI) const {
7693 // If we have (trunc (extract_vector_elt X, Y)), try to turn it into
7694 // (extract_vector_elt (bitcast X), Y'), where (bitcast X) has elements
7695 // of type TruncVT.
7696 if (Op.getOpcode() == ISD::EXTRACT_VECTOR_ELT &&
7697 TruncVT.getSizeInBits() % 8 == 0) {
7698 SDValue Vec = Op.getOperand(0);
7699 EVT VecVT = Vec.getValueType();
7700 if (canTreatAsByteVector(VecVT)) {
7701 if (auto *IndexN = dyn_cast<ConstantSDNode>(Op.getOperand(1))) {
7702 unsigned BytesPerElement = VecVT.getVectorElementType().getStoreSize();
7703 unsigned TruncBytes = TruncVT.getStoreSize();
7704 if (BytesPerElement % TruncBytes == 0) {
7705 // Calculate the value of Y' in the above description. We are
7706 // splitting the original elements into Scale equal-sized pieces
7707 // and for truncation purposes want the last (least-significant)
7708 // of these pieces for IndexN. This is easiest to do by calculating
7709 // the start index of the following element and then subtracting 1.
7710 unsigned Scale = BytesPerElement / TruncBytes;
7711 unsigned NewIndex = (IndexN->getZExtValue() + 1) * Scale - 1;
7712
7713 // Defer the creation of the bitcast from X to combineExtract,
7714 // which might be able to optimize the extraction.
7715 VecVT = EVT::getVectorVT(*DCI.DAG.getContext(),
7716 MVT::getIntegerVT(TruncBytes * 8),
7717 VecVT.getStoreSize() / TruncBytes);
7718 EVT ResVT = (TruncBytes < 4 ? MVT::i32 : TruncVT);
7719 return combineExtract(DL, ResVT, VecVT, Vec, NewIndex, DCI, true);
7720 }
7721 }
7722 }
7723 }
7724 return SDValue();
7725}
7726
7727SDValue SystemZTargetLowering::combineZERO_EXTEND(
7728 SDNode *N, DAGCombinerInfo &DCI) const {
7729 // Convert (zext (select_ccmask C1, C2)) into (select_ccmask C1', C2')
7730 SelectionDAG &DAG = DCI.DAG;
7731 SDValue N0 = N->getOperand(0);
7732 EVT VT = N->getValueType(0);
7733 if (N0.getOpcode() == SystemZISD::SELECT_CCMASK) {
7734 auto *TrueOp = dyn_cast<ConstantSDNode>(N0.getOperand(0));
7735 auto *FalseOp = dyn_cast<ConstantSDNode>(N0.getOperand(1));
7736 if (TrueOp && FalseOp) {
7737 SDLoc DL(N0);
7738 SDValue Ops[] = { DAG.getConstant(TrueOp->getZExtValue(), DL, VT),
7739 DAG.getConstant(FalseOp->getZExtValue(), DL, VT),
7740 N0.getOperand(2), N0.getOperand(3), N0.getOperand(4) };
7741 SDValue NewSelect = DAG.getNode(SystemZISD::SELECT_CCMASK, DL, VT, Ops);
7742 // If N0 has multiple uses, change other uses as well.
7743 if (!N0.hasOneUse()) {
7744 SDValue TruncSelect =
7745 DAG.getNode(ISD::TRUNCATE, DL, N0.getValueType(), NewSelect);
7746 DCI.CombineTo(N0.getNode(), TruncSelect);
7747 }
7748 return NewSelect;
7749 }
7750 }
7751 // Convert (zext (xor (trunc X), C)) into (xor (trunc X), C') if the size
7752 // of the result is smaller than the size of X and all the truncated bits
7753 // of X are already zero.
7754 if (N0.getOpcode() == ISD::XOR &&
7755 N0.hasOneUse() && N0.getOperand(0).hasOneUse() &&
7756 N0.getOperand(0).getOpcode() == ISD::TRUNCATE &&
7757 N0.getOperand(1).getOpcode() == ISD::Constant) {
7758 SDValue X = N0.getOperand(0).getOperand(0);
7759 if (VT.isScalarInteger() && VT.getSizeInBits() < X.getValueSizeInBits()) {
7760 KnownBits Known = DAG.computeKnownBits(X);
7761 APInt TruncatedBits = APInt::getBitsSet(X.getValueSizeInBits(),
7762 N0.getValueSizeInBits(),
7763 VT.getSizeInBits());
7764 if (TruncatedBits.isSubsetOf(Known.Zero)) {
7765 X = DAG.getNode(ISD::TRUNCATE, SDLoc(X), VT, X);
7766 APInt Mask = N0.getConstantOperandAPInt(1).zext(VT.getSizeInBits());
7767 return DAG.getNode(ISD::XOR, SDLoc(N0), VT,
7768 X, DAG.getConstant(Mask, SDLoc(N0), VT));
7769 }
7770 }
7771 }
7772 // Recognize patterns for VECTOR SUBTRACT COMPUTE BORROW INDICATION
7773 // and VECTOR ADD COMPUTE CARRY for i128:
7774 // (zext (setcc_uge X Y)) --> (VSCBI X Y)
7775 // (zext (setcc_ule Y X)) --> (VSCBI X Y)
7776 // (zext (setcc_ult (add X Y) X/Y) -> (VACC X Y)
7777 // (zext (setcc_ugt X/Y (add X Y)) -> (VACC X Y)
7778 // For vector types, these patterns are recognized in the .td file.
7779 if (N0.getOpcode() == ISD::SETCC && isTypeLegal(VT) && VT == MVT::i128 &&
7780 N0.getOperand(0).getValueType() == VT) {
7781 SDValue Op0 = N0.getOperand(0);
7782 SDValue Op1 = N0.getOperand(1);
7783 const ISD::CondCode CC = cast<CondCodeSDNode>(N0.getOperand(2))->get();
7784 switch (CC) {
7785 case ISD::SETULE:
7786 std::swap(Op0, Op1);
7787 [[fallthrough]];
7788 case ISD::SETUGE:
7789 return DAG.getNode(SystemZISD::VSCBI, SDLoc(N0), VT, Op0, Op1);
7790 case ISD::SETUGT:
7791 std::swap(Op0, Op1);
7792 [[fallthrough]];
7793 case ISD::SETULT:
7794 if (Op0->hasOneUse() && Op0->getOpcode() == ISD::ADD &&
7795 (Op0->getOperand(0) == Op1 || Op0->getOperand(1) == Op1))
7796 return DAG.getNode(SystemZISD::VACC, SDLoc(N0), VT, Op0->getOperand(0),
7797 Op0->getOperand(1));
7798 break;
7799 default:
7800 break;
7801 }
7802 }
7803
7804 return SDValue();
7805}
7806
7807SDValue SystemZTargetLowering::combineSIGN_EXTEND_INREG(
7808 SDNode *N, DAGCombinerInfo &DCI) const {
7809 // Convert (sext_in_reg (setcc LHS, RHS, COND), i1)
7810 // and (sext_in_reg (any_extend (setcc LHS, RHS, COND)), i1)
7811 // into (select_cc LHS, RHS, -1, 0, COND)
7812 SelectionDAG &DAG = DCI.DAG;
7813 SDValue N0 = N->getOperand(0);
7814 EVT VT = N->getValueType(0);
7815 EVT EVT = cast<VTSDNode>(N->getOperand(1))->getVT();
7816 if (N0.hasOneUse() && N0.getOpcode() == ISD::ANY_EXTEND)
7817 N0 = N0.getOperand(0);
7818 if (EVT == MVT::i1 && N0.hasOneUse() && N0.getOpcode() == ISD::SETCC) {
7819 SDLoc DL(N0);
7820 SDValue Ops[] = { N0.getOperand(0), N0.getOperand(1),
7821 DAG.getAllOnesConstant(DL, VT),
7822 DAG.getConstant(0, DL, VT), N0.getOperand(2) };
7823 return DAG.getNode(ISD::SELECT_CC, DL, VT, Ops);
7824 }
7825 return SDValue();
7826}
7827
7828SDValue SystemZTargetLowering::combineSIGN_EXTEND(
7829 SDNode *N, DAGCombinerInfo &DCI) const {
7830 // Convert (sext (ashr (shl X, C1), C2)) to
7831 // (ashr (shl (anyext X), C1'), C2')), since wider shifts are as
7832 // cheap as narrower ones.
7833 SelectionDAG &DAG = DCI.DAG;
7834 SDValue N0 = N->getOperand(0);
7835 EVT VT = N->getValueType(0);
7836 if (N0.hasOneUse() && N0.getOpcode() == ISD::SRA) {
7837 auto *SraAmt = dyn_cast<ConstantSDNode>(N0.getOperand(1));
7838 SDValue Inner = N0.getOperand(0);
7839 if (SraAmt && Inner.hasOneUse() && Inner.getOpcode() == ISD::SHL) {
7840 if (auto *ShlAmt = dyn_cast<ConstantSDNode>(Inner.getOperand(1))) {
7841 unsigned Extra = (VT.getSizeInBits() - N0.getValueSizeInBits());
7842 unsigned NewShlAmt = ShlAmt->getZExtValue() + Extra;
7843 unsigned NewSraAmt = SraAmt->getZExtValue() + Extra;
7844 EVT ShiftVT = N0.getOperand(1).getValueType();
7845 SDValue Ext = DAG.getNode(ISD::ANY_EXTEND, SDLoc(Inner), VT,
7846 Inner.getOperand(0));
7847 SDValue Shl = DAG.getNode(ISD::SHL, SDLoc(Inner), VT, Ext,
7848 DAG.getConstant(NewShlAmt, SDLoc(Inner),
7849 ShiftVT));
7850 return DAG.getNode(ISD::SRA, SDLoc(N0), VT, Shl,
7851 DAG.getConstant(NewSraAmt, SDLoc(N0), ShiftVT));
7852 }
7853 }
7854 }
7855
7856 return SDValue();
7857}
7858
7859SDValue SystemZTargetLowering::combineMERGE(
7860 SDNode *N, DAGCombinerInfo &DCI) const {
7861 SelectionDAG &DAG = DCI.DAG;
7862 unsigned Opcode = N->getOpcode();
7863 SDValue Op0 = N->getOperand(0);
7864 SDValue Op1 = N->getOperand(1);
7865 if (Op0.getOpcode() == ISD::BITCAST)
7866 Op0 = Op0.getOperand(0);
7868 // (z_merge_* 0, 0) -> 0. This is mostly useful for using VLLEZF
7869 // for v4f32.
7870 if (Op1 == N->getOperand(0))
7871 return Op1;
7872 // (z_merge_? 0, X) -> (z_unpackl_? 0, X).
7873 EVT VT = Op1.getValueType();
7874 unsigned ElemBytes = VT.getVectorElementType().getStoreSize();
7875 if (ElemBytes <= 4) {
7876 Opcode = (Opcode == SystemZISD::MERGE_HIGH ?
7877 SystemZISD::UNPACKL_HIGH : SystemZISD::UNPACKL_LOW);
7878 EVT InVT = VT.changeVectorElementTypeToInteger();
7879 EVT OutVT = MVT::getVectorVT(MVT::getIntegerVT(ElemBytes * 16),
7880 SystemZ::VectorBytes / ElemBytes / 2);
7881 if (VT != InVT) {
7882 Op1 = DAG.getNode(ISD::BITCAST, SDLoc(N), InVT, Op1);
7883 DCI.AddToWorklist(Op1.getNode());
7884 }
7885 SDValue Op = DAG.getNode(Opcode, SDLoc(N), OutVT, Op1);
7886 DCI.AddToWorklist(Op.getNode());
7887 return DAG.getNode(ISD::BITCAST, SDLoc(N), VT, Op);
7888 }
7889 }
7890 return SDValue();
7891}
7892
7893static bool isI128MovedToParts(LoadSDNode *LD, SDNode *&LoPart,
7894 SDNode *&HiPart) {
7895 LoPart = HiPart = nullptr;
7896
7897 // Scan through all users.
7898 for (SDUse &Use : LD->uses()) {
7899 // Skip the uses of the chain.
7900 if (Use.getResNo() != 0)
7901 continue;
7902
7903 // Verify every user is a TRUNCATE to i64 of the low or high half.
7904 SDNode *User = Use.getUser();
7905 bool IsLoPart = true;
7906 if (User->getOpcode() == ISD::SRL &&
7907 User->getOperand(1).getOpcode() == ISD::Constant &&
7908 User->getConstantOperandVal(1) == 64 && User->hasOneUse()) {
7909 User = *User->user_begin();
7910 IsLoPart = false;
7911 }
7912 if (User->getOpcode() != ISD::TRUNCATE || User->getValueType(0) != MVT::i64)
7913 return false;
7914
7915 if (IsLoPart) {
7916 if (LoPart)
7917 return false;
7918 LoPart = User;
7919 } else {
7920 if (HiPart)
7921 return false;
7922 HiPart = User;
7923 }
7924 }
7925 return true;
7926}
7927
7928static bool isF128MovedToParts(LoadSDNode *LD, SDNode *&LoPart,
7929 SDNode *&HiPart) {
7930 LoPart = HiPart = nullptr;
7931
7932 // Scan through all users.
7933 for (SDUse &Use : LD->uses()) {
7934 // Skip the uses of the chain.
7935 if (Use.getResNo() != 0)
7936 continue;
7937
7938 // Verify every user is an EXTRACT_SUBREG of the low or high half.
7939 SDNode *User = Use.getUser();
7940 if (!User->hasOneUse() || !User->isMachineOpcode() ||
7941 User->getMachineOpcode() != TargetOpcode::EXTRACT_SUBREG)
7942 return false;
7943
7944 switch (User->getConstantOperandVal(1)) {
7945 case SystemZ::subreg_l64:
7946 if (LoPart)
7947 return false;
7948 LoPart = User;
7949 break;
7950 case SystemZ::subreg_h64:
7951 if (HiPart)
7952 return false;
7953 HiPart = User;
7954 break;
7955 default:
7956 return false;
7957 }
7958 }
7959 return true;
7960}
7961
7962SDValue SystemZTargetLowering::combineLOAD(
7963 SDNode *N, DAGCombinerInfo &DCI) const {
7964 SelectionDAG &DAG = DCI.DAG;
7965 EVT LdVT = N->getValueType(0);
7966 if (auto *LN = dyn_cast<LoadSDNode>(N)) {
7967 if (LN->getAddressSpace() == SYSTEMZAS::PTR32) {
7968 MVT PtrVT = getPointerTy(DAG.getDataLayout());
7969 MVT LoadNodeVT = LN->getBasePtr().getSimpleValueType();
7970 if (PtrVT != LoadNodeVT) {
7971 SDLoc DL(LN);
7972 SDValue AddrSpaceCast = DAG.getAddrSpaceCast(
7973 DL, PtrVT, LN->getBasePtr(), SYSTEMZAS::PTR32, 0);
7974 return DAG.getExtLoad(LN->getExtensionType(), DL, LN->getValueType(0),
7975 LN->getChain(), AddrSpaceCast, LN->getMemoryVT(),
7976 LN->getMemOperand());
7977 }
7978 }
7979 }
7980 SDLoc DL(N);
7981
7982 // Replace a 128-bit load that is used solely to move its value into GPRs
7983 // by separate loads of both halves.
7984 LoadSDNode *LD = cast<LoadSDNode>(N);
7985 if (LD->isSimple() && ISD::isNormalLoad(LD)) {
7986 SDNode *LoPart, *HiPart;
7987 if ((LdVT == MVT::i128 && isI128MovedToParts(LD, LoPart, HiPart)) ||
7988 (LdVT == MVT::f128 && isF128MovedToParts(LD, LoPart, HiPart))) {
7989 // Rewrite each extraction as an independent load.
7990 SmallVector<SDValue, 2> ArgChains;
7991 if (HiPart) {
7992 SDValue EltLoad = DAG.getLoad(
7993 HiPart->getValueType(0), DL, LD->getChain(), LD->getBasePtr(),
7994 LD->getPointerInfo(), LD->getBaseAlign(),
7995 LD->getMemOperand()->getFlags(), LD->getAAInfo());
7996
7997 DCI.CombineTo(HiPart, EltLoad, true);
7998 ArgChains.push_back(EltLoad.getValue(1));
7999 }
8000 if (LoPart) {
8001 SDValue EltLoad = DAG.getLoad(
8002 LoPart->getValueType(0), DL, LD->getChain(),
8003 DAG.getObjectPtrOffset(DL, LD->getBasePtr(), TypeSize::getFixed(8)),
8004 LD->getPointerInfo().getWithOffset(8), LD->getBaseAlign(),
8005 LD->getMemOperand()->getFlags(), LD->getAAInfo());
8006
8007 DCI.CombineTo(LoPart, EltLoad, true);
8008 ArgChains.push_back(EltLoad.getValue(1));
8009 }
8010
8011 // Collect all chains via TokenFactor.
8012 SDValue Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, ArgChains);
8013 DAG.ReplaceAllUsesOfValueWith(SDValue(N, 1), Chain);
8014 DCI.AddToWorklist(Chain.getNode());
8015 return SDValue(N, 0);
8016 }
8017 }
8018
8019 if (LdVT.isVector() || LdVT.isInteger())
8020 return SDValue();
8021 // Transform a scalar load that is REPLICATEd as well as having other
8022 // use(s) to the form where the other use(s) use the first element of the
8023 // REPLICATE instead of the load. Otherwise instruction selection will not
8024 // produce a VLREP. Avoid extracting to a GPR, so only do this for floating
8025 // point loads.
8026
8027 SDValue Replicate;
8028 SmallVector<SDNode*, 8> OtherUses;
8029 for (SDUse &Use : N->uses()) {
8030 if (Use.getUser()->getOpcode() == SystemZISD::REPLICATE) {
8031 if (Replicate)
8032 return SDValue(); // Should never happen
8033 Replicate = SDValue(Use.getUser(), 0);
8034 } else if (Use.getResNo() == 0)
8035 OtherUses.push_back(Use.getUser());
8036 }
8037 if (!Replicate || OtherUses.empty())
8038 return SDValue();
8039
8040 SDValue Extract0 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, LdVT,
8041 Replicate, DAG.getConstant(0, DL, MVT::i32));
8042 // Update uses of the loaded Value while preserving old chains.
8043 for (SDNode *U : OtherUses) {
8045 for (SDValue Op : U->ops())
8046 Ops.push_back((Op.getNode() == N && Op.getResNo() == 0) ? Extract0 : Op);
8047 DAG.UpdateNodeOperands(U, Ops);
8048 }
8049 return SDValue(N, 0);
8050}
8051
8052bool SystemZTargetLowering::canLoadStoreByteSwapped(EVT VT) const {
8053 if (VT == MVT::i16 || VT == MVT::i32 || VT == MVT::i64)
8054 return true;
8055 if (Subtarget.hasVectorEnhancements2())
8056 if (VT == MVT::v8i16 || VT == MVT::v4i32 || VT == MVT::v2i64 || VT == MVT::i128)
8057 return true;
8058 return false;
8059}
8060
8062 if (!VT.isVector() || !VT.isSimple() ||
8063 VT.getSizeInBits() != 128 ||
8064 VT.getScalarSizeInBits() % 8 != 0)
8065 return false;
8066
8067 unsigned NumElts = VT.getVectorNumElements();
8068 for (unsigned i = 0; i < NumElts; ++i) {
8069 if (M[i] < 0) continue; // ignore UNDEF indices
8070 if ((unsigned) M[i] != NumElts - 1 - i)
8071 return false;
8072 }
8073
8074 return true;
8075}
8076
8077static bool isOnlyUsedByStores(SDValue StoredVal, SelectionDAG &DAG) {
8078 for (auto *U : StoredVal->users()) {
8079 if (StoreSDNode *ST = dyn_cast<StoreSDNode>(U)) {
8080 EVT CurrMemVT = ST->getMemoryVT().getScalarType();
8081 if (CurrMemVT.isRound() && CurrMemVT.getStoreSize() <= 16)
8082 continue;
8083 } else if (isa<BuildVectorSDNode>(U)) {
8084 SDValue BuildVector = SDValue(U, 0);
8085 if (DAG.isSplatValue(BuildVector, true/*AllowUndefs*/) &&
8086 isOnlyUsedByStores(BuildVector, DAG))
8087 continue;
8088 }
8089 return false;
8090 }
8091 return true;
8092}
8093
8094static bool isI128MovedFromParts(SDValue Val, SDValue &LoPart,
8095 SDValue &HiPart) {
8096 if (Val.getOpcode() != ISD::OR || !Val.getNode()->hasOneUse())
8097 return false;
8098
8099 SDValue Op0 = Val.getOperand(0);
8100 SDValue Op1 = Val.getOperand(1);
8101
8102 if (Op0.getOpcode() == ISD::SHL)
8103 std::swap(Op0, Op1);
8104 if (Op1.getOpcode() != ISD::SHL || !Op1.getNode()->hasOneUse() ||
8105 Op1.getOperand(1).getOpcode() != ISD::Constant ||
8106 Op1.getConstantOperandVal(1) != 64)
8107 return false;
8108 Op1 = Op1.getOperand(0);
8109
8110 if (Op0.getOpcode() != ISD::ZERO_EXTEND || !Op0.getNode()->hasOneUse() ||
8111 Op0.getOperand(0).getValueType() != MVT::i64)
8112 return false;
8113 if (Op1.getOpcode() != ISD::ANY_EXTEND || !Op1.getNode()->hasOneUse() ||
8114 Op1.getOperand(0).getValueType() != MVT::i64)
8115 return false;
8116
8117 LoPart = Op0.getOperand(0);
8118 HiPart = Op1.getOperand(0);
8119 return true;
8120}
8121
8122static bool isF128MovedFromParts(SDValue Val, SDValue &LoPart,
8123 SDValue &HiPart) {
8124 if (!Val.getNode()->hasOneUse() || !Val.isMachineOpcode() ||
8125 Val.getMachineOpcode() != TargetOpcode::REG_SEQUENCE)
8126 return false;
8127
8128 if (Val->getNumOperands() != 5 ||
8129 Val->getOperand(0)->getAsZExtVal() != SystemZ::FP128BitRegClassID ||
8130 Val->getOperand(2)->getAsZExtVal() != SystemZ::subreg_l64 ||
8131 Val->getOperand(4)->getAsZExtVal() != SystemZ::subreg_h64)
8132 return false;
8133
8134 LoPart = Val->getOperand(1);
8135 HiPart = Val->getOperand(3);
8136 return true;
8137}
8138
8139SDValue SystemZTargetLowering::combineSTORE(
8140 SDNode *N, DAGCombinerInfo &DCI) const {
8141 SelectionDAG &DAG = DCI.DAG;
8142 auto *SN = cast<StoreSDNode>(N);
8143 auto &Op1 = N->getOperand(1);
8144 EVT MemVT = SN->getMemoryVT();
8145
8146 if (SN->getAddressSpace() == SYSTEMZAS::PTR32) {
8147 MVT PtrVT = getPointerTy(DAG.getDataLayout());
8148 MVT StoreNodeVT = SN->getBasePtr().getSimpleValueType();
8149 if (PtrVT != StoreNodeVT) {
8150 SDLoc DL(SN);
8151 SDValue AddrSpaceCast = DAG.getAddrSpaceCast(DL, PtrVT, SN->getBasePtr(),
8152 SYSTEMZAS::PTR32, 0);
8153 return DAG.getStore(SN->getChain(), DL, SN->getValue(), AddrSpaceCast,
8154 SN->getPointerInfo(), SN->getBaseAlign(),
8155 SN->getMemOperand()->getFlags(), SN->getAAInfo());
8156 }
8157 }
8158
8159 // If we have (truncstoreiN (extract_vector_elt X, Y), Z) then it is better
8160 // for the extraction to be done on a vMiN value, so that we can use VSTE.
8161 // If X has wider elements then convert it to:
8162 // (truncstoreiN (extract_vector_elt (bitcast X), Y2), Z).
8163 if (MemVT.isInteger() && SN->isTruncatingStore()) {
8164 if (SDValue Value =
8165 combineTruncateExtract(SDLoc(N), MemVT, SN->getValue(), DCI)) {
8166 DCI.AddToWorklist(Value.getNode());
8167
8168 // Rewrite the store with the new form of stored value.
8169 return DAG.getTruncStore(SN->getChain(), SDLoc(SN), Value,
8170 SN->getBasePtr(), SN->getMemoryVT(),
8171 SN->getMemOperand());
8172 }
8173 }
8174
8175 // combine STORE (LOAD_STACK_GUARD) into MOV_STACKGUARD_DAG
8176 if (Op1->isMachineOpcode() &&
8177 (Op1->getMachineOpcode() == SystemZ::LOAD_STACK_GUARD)) {
8178 // Obtain the frame index the store was targeting.
8179 int FI = cast<FrameIndexSDNode>(SN->getOperand(2))->getIndex();
8180 // Prepare operands of the MOV_STACKGUARD ISD Node - Chain and FrameIndex.
8181 SDValue Ops[] = {SN->getChain(), DAG.getTargetFrameIndex(FI, MVT::i64)};
8182 return DAG.getNode(SystemZISD::MOV_STACKGUARD, SDLoc(SN), MVT::Other, Ops);
8183 }
8184
8185 // Combine STORE (BSWAP) into STRVH/STRV/STRVG/VSTBR
8186 if (!SN->isTruncatingStore() &&
8187 Op1.getOpcode() == ISD::BSWAP &&
8188 Op1.getNode()->hasOneUse() &&
8189 canLoadStoreByteSwapped(Op1.getValueType())) {
8190
8191 SDValue BSwapOp = Op1.getOperand(0);
8192
8193 if (BSwapOp.getValueType() == MVT::i16)
8194 BSwapOp = DAG.getNode(ISD::ANY_EXTEND, SDLoc(N), MVT::i32, BSwapOp);
8195
8196 SDValue Ops[] = {
8197 N->getOperand(0), BSwapOp, N->getOperand(2)
8198 };
8199
8200 return
8201 DAG.getMemIntrinsicNode(SystemZISD::STRV, SDLoc(N), DAG.getVTList(MVT::Other),
8202 Ops, MemVT, SN->getMemOperand());
8203 }
8204 // Combine STORE (element-swap) into VSTER
8205 if (!SN->isTruncatingStore() &&
8206 Op1.getOpcode() == ISD::VECTOR_SHUFFLE &&
8207 Op1.getNode()->hasOneUse() &&
8208 Subtarget.hasVectorEnhancements2()) {
8209 ShuffleVectorSDNode *SVN = cast<ShuffleVectorSDNode>(Op1.getNode());
8210 ArrayRef<int> ShuffleMask = SVN->getMask();
8211 if (isVectorElementSwap(ShuffleMask, Op1.getValueType())) {
8212 SDValue Ops[] = {
8213 N->getOperand(0), Op1.getOperand(0), N->getOperand(2)
8214 };
8215
8216 return DAG.getMemIntrinsicNode(SystemZISD::VSTER, SDLoc(N),
8217 DAG.getVTList(MVT::Other),
8218 Ops, MemVT, SN->getMemOperand());
8219 }
8220 }
8221
8222 // Combine STORE (READCYCLECOUNTER) into STCKF.
8223 if (!SN->isTruncatingStore() &&
8225 Op1.hasOneUse() &&
8226 N->getOperand(0).reachesChainWithoutSideEffects(SDValue(Op1.getNode(), 1))) {
8227 SDValue Ops[] = { Op1.getOperand(0), N->getOperand(2) };
8228 return DAG.getMemIntrinsicNode(SystemZISD::STCKF, SDLoc(N),
8229 DAG.getVTList(MVT::Other),
8230 Ops, MemVT, SN->getMemOperand());
8231 }
8232
8233 // Transform a store of a 128-bit value moved from parts into two stores.
8234 if (SN->isSimple() && ISD::isNormalStore(SN)) {
8235 SDValue LoPart, HiPart;
8236 if ((MemVT == MVT::i128 && isI128MovedFromParts(Op1, LoPart, HiPart)) ||
8237 (MemVT == MVT::f128 && isF128MovedFromParts(Op1, LoPart, HiPart))) {
8238 SDLoc DL(SN);
8239 SDValue Chain0 = DAG.getStore(
8240 SN->getChain(), DL, HiPart, SN->getBasePtr(), SN->getPointerInfo(),
8241 SN->getBaseAlign(), SN->getMemOperand()->getFlags(), SN->getAAInfo());
8242 SDValue Chain1 = DAG.getStore(
8243 SN->getChain(), DL, LoPart,
8244 DAG.getObjectPtrOffset(DL, SN->getBasePtr(), TypeSize::getFixed(8)),
8245 SN->getPointerInfo().getWithOffset(8), SN->getBaseAlign(),
8246 SN->getMemOperand()->getFlags(), SN->getAAInfo());
8247
8248 return DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Chain0, Chain1);
8249 }
8250 }
8251
8252 // Replicate a reg or immediate with VREP instead of scalar multiply or
8253 // immediate load. It seems best to do this during the first DAGCombine as
8254 // it is straight-forward to handle the zero-extend node in the initial
8255 // DAG, and also not worry about the keeping the new MemVT legal (e.g. when
8256 // extracting an i16 element from a v16i8 vector).
8257 if (Subtarget.hasVector() && DCI.Level == BeforeLegalizeTypes &&
8258 isOnlyUsedByStores(Op1, DAG)) {
8259 SDValue Word = SDValue();
8260 EVT WordVT;
8261
8262 // Find a replicated immediate and return it if found in Word and its
8263 // type in WordVT.
8264 auto FindReplicatedImm = [&](ConstantSDNode *C, unsigned TotBytes) {
8265 // Some constants are better handled with a scalar store.
8266 if (C->getAPIntValue().getBitWidth() > 64 || C->isAllOnes() ||
8267 isInt<16>(C->getSExtValue()) || MemVT.getStoreSize() <= 2)
8268 return;
8269
8270 APInt Val = C->getAPIntValue();
8271 // Truncate Val in case of a truncating store.
8272 if (!llvm::isUIntN(TotBytes * 8, Val.getZExtValue())) {
8273 assert(SN->isTruncatingStore() &&
8274 "Non-truncating store and immediate value does not fit?");
8275 Val = Val.trunc(TotBytes * 8);
8276 }
8277
8278 SystemZVectorConstantInfo VCI(APInt(TotBytes * 8, Val.getZExtValue()));
8279 if (VCI.isVectorConstantLegal(Subtarget) &&
8280 VCI.Opcode == SystemZISD::REPLICATE) {
8281 Word = DAG.getConstant(VCI.OpVals[0], SDLoc(SN), MVT::i32);
8282 WordVT = VCI.VecVT.getScalarType();
8283 }
8284 };
8285
8286 // Find a replicated register and return it if found in Word and its type
8287 // in WordVT.
8288 auto FindReplicatedReg = [&](SDValue MulOp) {
8289 EVT MulVT = MulOp.getValueType();
8290 if (MulOp->getOpcode() == ISD::MUL &&
8291 (MulVT == MVT::i16 || MulVT == MVT::i32 || MulVT == MVT::i64)) {
8292 // Find a zero extended value and its type.
8293 SDValue LHS = MulOp->getOperand(0);
8294 if (LHS->getOpcode() == ISD::ZERO_EXTEND)
8295 WordVT = LHS->getOperand(0).getValueType();
8296 else if (LHS->getOpcode() == ISD::AssertZext)
8297 WordVT = cast<VTSDNode>(LHS->getOperand(1))->getVT();
8298 else
8299 return;
8300 // Find a replicating constant, e.g. 0x00010001.
8301 if (auto *C = dyn_cast<ConstantSDNode>(MulOp->getOperand(1))) {
8302 SystemZVectorConstantInfo VCI(
8303 APInt(MulVT.getSizeInBits(), C->getZExtValue()));
8304 if (VCI.isVectorConstantLegal(Subtarget) &&
8305 VCI.Opcode == SystemZISD::REPLICATE && VCI.OpVals[0] == 1 &&
8306 WordVT == VCI.VecVT.getScalarType())
8307 Word = DAG.getZExtOrTrunc(LHS->getOperand(0), SDLoc(SN), WordVT);
8308 }
8309 }
8310 };
8311
8312 if (isa<BuildVectorSDNode>(Op1) &&
8313 DAG.isSplatValue(Op1, true/*AllowUndefs*/)) {
8314 SDValue SplatVal = Op1->getOperand(0);
8315 if (auto *C = dyn_cast<ConstantSDNode>(SplatVal))
8316 FindReplicatedImm(C, SplatVal.getValueType().getStoreSize());
8317 else
8318 FindReplicatedReg(SplatVal);
8319 } else {
8320 if (auto *C = dyn_cast<ConstantSDNode>(Op1))
8321 FindReplicatedImm(C, MemVT.getStoreSize());
8322 else
8323 FindReplicatedReg(Op1);
8324 }
8325
8326 if (Word != SDValue()) {
8327 assert(MemVT.getSizeInBits() % WordVT.getSizeInBits() == 0 &&
8328 "Bad type handling");
8329 unsigned NumElts = MemVT.getSizeInBits() / WordVT.getSizeInBits();
8330 EVT SplatVT = EVT::getVectorVT(*DAG.getContext(), WordVT, NumElts);
8331 SDValue SplatVal = DAG.getSplatVector(SplatVT, SDLoc(SN), Word);
8332 return DAG.getStore(SN->getChain(), SDLoc(SN), SplatVal,
8333 SN->getBasePtr(), SN->getMemOperand());
8334 }
8335 }
8336
8337 return SDValue();
8338}
8339
8340SDValue SystemZTargetLowering::combineVECTOR_SHUFFLE(
8341 SDNode *N, DAGCombinerInfo &DCI) const {
8342 SelectionDAG &DAG = DCI.DAG;
8343 // Combine element-swap (LOAD) into VLER
8344 if (ISD::isNON_EXTLoad(N->getOperand(0).getNode()) &&
8345 N->getOperand(0).hasOneUse() &&
8346 Subtarget.hasVectorEnhancements2()) {
8347 ShuffleVectorSDNode *SVN = cast<ShuffleVectorSDNode>(N);
8348 ArrayRef<int> ShuffleMask = SVN->getMask();
8349 if (isVectorElementSwap(ShuffleMask, N->getValueType(0))) {
8350 SDValue Load = N->getOperand(0);
8351 LoadSDNode *LD = cast<LoadSDNode>(Load);
8352
8353 // Create the element-swapping load.
8354 SDValue Ops[] = {
8355 LD->getChain(), // Chain
8356 LD->getBasePtr() // Ptr
8357 };
8358 SDValue ESLoad =
8359 DAG.getMemIntrinsicNode(SystemZISD::VLER, SDLoc(N),
8360 DAG.getVTList(LD->getValueType(0), MVT::Other),
8361 Ops, LD->getMemoryVT(), LD->getMemOperand());
8362
8363 // First, combine the VECTOR_SHUFFLE away. This makes the value produced
8364 // by the load dead.
8365 DCI.CombineTo(N, ESLoad);
8366
8367 // Next, combine the load away, we give it a bogus result value but a real
8368 // chain result. The result value is dead because the shuffle is dead.
8369 DCI.CombineTo(Load.getNode(), ESLoad, ESLoad.getValue(1));
8370
8371 // Return N so it doesn't get rechecked!
8372 return SDValue(N, 0);
8373 }
8374 }
8375
8376 return SDValue();
8377}
8378
8379SDValue SystemZTargetLowering::combineEXTRACT_VECTOR_ELT(
8380 SDNode *N, DAGCombinerInfo &DCI) const {
8381 SelectionDAG &DAG = DCI.DAG;
8382
8383 if (!Subtarget.hasVector())
8384 return SDValue();
8385
8386 // Look through bitcasts that retain the number of vector elements.
8387 SDValue Op = N->getOperand(0);
8388 if (Op.getOpcode() == ISD::BITCAST &&
8389 Op.getValueType().isVector() &&
8390 Op.getOperand(0).getValueType().isVector() &&
8391 Op.getValueType().getVectorNumElements() ==
8392 Op.getOperand(0).getValueType().getVectorNumElements())
8393 Op = Op.getOperand(0);
8394
8395 // Pull BSWAP out of a vector extraction.
8396 if (Op.getOpcode() == ISD::BSWAP && Op.hasOneUse()) {
8397 EVT VecVT = Op.getValueType();
8398 EVT EltVT = VecVT.getVectorElementType();
8399 Op = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SDLoc(N), EltVT,
8400 Op.getOperand(0), N->getOperand(1));
8401 DCI.AddToWorklist(Op.getNode());
8402 Op = DAG.getNode(ISD::BSWAP, SDLoc(N), EltVT, Op);
8403 if (EltVT != N->getValueType(0)) {
8404 DCI.AddToWorklist(Op.getNode());
8405 Op = DAG.getNode(ISD::BITCAST, SDLoc(N), N->getValueType(0), Op);
8406 }
8407 return Op;
8408 }
8409
8410 // Try to simplify a vector extraction.
8411 if (auto *IndexN = dyn_cast<ConstantSDNode>(N->getOperand(1))) {
8412 SDValue Op0 = N->getOperand(0);
8413 EVT VecVT = Op0.getValueType();
8414 if (canTreatAsByteVector(VecVT))
8415 return combineExtract(SDLoc(N), N->getValueType(0), VecVT, Op0,
8416 IndexN->getZExtValue(), DCI, false);
8417 }
8418 return SDValue();
8419}
8420
8421SDValue SystemZTargetLowering::combineJOIN_DWORDS(
8422 SDNode *N, DAGCombinerInfo &DCI) const {
8423 SelectionDAG &DAG = DCI.DAG;
8424 // (join_dwords X, X) == (replicate X)
8425 if (N->getOperand(0) == N->getOperand(1))
8426 return DAG.getNode(SystemZISD::REPLICATE, SDLoc(N), N->getValueType(0),
8427 N->getOperand(0));
8428 return SDValue();
8429}
8430
8432 SDValue Chain1 = N1->getOperand(0);
8433 SDValue Chain2 = N2->getOperand(0);
8434
8435 // Trivial case: both nodes take the same chain.
8436 if (Chain1 == Chain2)
8437 return Chain1;
8438
8439 // FIXME - we could handle more complex cases via TokenFactor,
8440 // assuming we can verify that this would not create a cycle.
8441 return SDValue();
8442}
8443
8444SDValue SystemZTargetLowering::combineFP_ROUND(
8445 SDNode *N, DAGCombinerInfo &DCI) const {
8446
8447 if (!Subtarget.hasVector())
8448 return SDValue();
8449
8450 // (fpround (extract_vector_elt X 0))
8451 // (fpround (extract_vector_elt X 1)) ->
8452 // (extract_vector_elt (VROUND X) 0)
8453 // (extract_vector_elt (VROUND X) 2)
8454 //
8455 // This is a special case since the target doesn't really support v2f32s.
8456 unsigned OpNo = N->isStrictFPOpcode() ? 1 : 0;
8457 SelectionDAG &DAG = DCI.DAG;
8458 SDValue Op0 = N->getOperand(OpNo);
8459 if (N->getValueType(0) == MVT::f32 && Op0.hasOneUse() &&
8461 Op0.getOperand(0).getValueType() == MVT::v2f64 &&
8462 Op0.getOperand(1).getOpcode() == ISD::Constant &&
8463 Op0.getConstantOperandVal(1) == 0) {
8464 SDValue Vec = Op0.getOperand(0);
8465 for (auto *U : Vec->users()) {
8466 if (U != Op0.getNode() && U->hasOneUse() &&
8467 U->getOpcode() == ISD::EXTRACT_VECTOR_ELT &&
8468 U->getOperand(0) == Vec &&
8469 U->getOperand(1).getOpcode() == ISD::Constant &&
8470 U->getConstantOperandVal(1) == 1) {
8471 SDValue OtherRound = SDValue(*U->user_begin(), 0);
8472 if (OtherRound.getOpcode() == N->getOpcode() &&
8473 OtherRound.getOperand(OpNo) == SDValue(U, 0) &&
8474 OtherRound.getValueType() == MVT::f32) {
8475 SDValue VRound, Chain;
8476 if (N->isStrictFPOpcode()) {
8477 Chain = MergeInputChains(N, OtherRound.getNode());
8478 if (!Chain)
8479 continue;
8480 VRound = DAG.getNode(SystemZISD::STRICT_VROUND, SDLoc(N),
8481 {MVT::v4f32, MVT::Other}, {Chain, Vec});
8482 Chain = VRound.getValue(1);
8483 } else
8484 VRound = DAG.getNode(SystemZISD::VROUND, SDLoc(N),
8485 MVT::v4f32, Vec);
8486 DCI.AddToWorklist(VRound.getNode());
8487 SDValue Extract1 =
8488 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SDLoc(U), MVT::f32,
8489 VRound, DAG.getConstant(2, SDLoc(U), MVT::i32));
8490 DCI.AddToWorklist(Extract1.getNode());
8491 DAG.ReplaceAllUsesOfValueWith(OtherRound, Extract1);
8492 if (Chain)
8493 DAG.ReplaceAllUsesOfValueWith(OtherRound.getValue(1), Chain);
8494 SDValue Extract0 =
8495 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SDLoc(Op0), MVT::f32,
8496 VRound, DAG.getConstant(0, SDLoc(Op0), MVT::i32));
8497 if (Chain)
8498 return DAG.getNode(ISD::MERGE_VALUES, SDLoc(Op0),
8499 N->getVTList(), Extract0, Chain);
8500 return Extract0;
8501 }
8502 }
8503 }
8504 }
8505 return SDValue();
8506}
8507
8508SDValue SystemZTargetLowering::combineFP_EXTEND(
8509 SDNode *N, DAGCombinerInfo &DCI) const {
8510
8511 if (!Subtarget.hasVector())
8512 return SDValue();
8513
8514 // (fpextend (extract_vector_elt X 0))
8515 // (fpextend (extract_vector_elt X 2)) ->
8516 // (extract_vector_elt (VEXTEND X) 0)
8517 // (extract_vector_elt (VEXTEND X) 1)
8518 //
8519 // This is a special case since the target doesn't really support v2f32s.
8520 unsigned OpNo = N->isStrictFPOpcode() ? 1 : 0;
8521 SelectionDAG &DAG = DCI.DAG;
8522 SDValue Op0 = N->getOperand(OpNo);
8523 if (N->getValueType(0) == MVT::f64 && Op0.hasOneUse() &&
8525 Op0.getOperand(0).getValueType() == MVT::v4f32 &&
8526 Op0.getOperand(1).getOpcode() == ISD::Constant &&
8527 Op0.getConstantOperandVal(1) == 0) {
8528 SDValue Vec = Op0.getOperand(0);
8529 for (auto *U : Vec->users()) {
8530 if (U != Op0.getNode() && U->hasOneUse() &&
8531 U->getOpcode() == ISD::EXTRACT_VECTOR_ELT &&
8532 U->getOperand(0) == Vec &&
8533 U->getOperand(1).getOpcode() == ISD::Constant &&
8534 U->getConstantOperandVal(1) == 2) {
8535 SDValue OtherExtend = SDValue(*U->user_begin(), 0);
8536 if (OtherExtend.getOpcode() == N->getOpcode() &&
8537 OtherExtend.getOperand(OpNo) == SDValue(U, 0) &&
8538 OtherExtend.getValueType() == MVT::f64) {
8539 SDValue VExtend, Chain;
8540 if (N->isStrictFPOpcode()) {
8541 Chain = MergeInputChains(N, OtherExtend.getNode());
8542 if (!Chain)
8543 continue;
8544 VExtend = DAG.getNode(SystemZISD::STRICT_VEXTEND, SDLoc(N),
8545 {MVT::v2f64, MVT::Other}, {Chain, Vec});
8546 Chain = VExtend.getValue(1);
8547 } else
8548 VExtend = DAG.getNode(SystemZISD::VEXTEND, SDLoc(N),
8549 MVT::v2f64, Vec);
8550 DCI.AddToWorklist(VExtend.getNode());
8551 SDValue Extract1 =
8552 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SDLoc(U), MVT::f64,
8553 VExtend, DAG.getConstant(1, SDLoc(U), MVT::i32));
8554 DCI.AddToWorklist(Extract1.getNode());
8555 DAG.ReplaceAllUsesOfValueWith(OtherExtend, Extract1);
8556 if (Chain)
8557 DAG.ReplaceAllUsesOfValueWith(OtherExtend.getValue(1), Chain);
8558 SDValue Extract0 =
8559 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SDLoc(Op0), MVT::f64,
8560 VExtend, DAG.getConstant(0, SDLoc(Op0), MVT::i32));
8561 if (Chain)
8562 return DAG.getNode(ISD::MERGE_VALUES, SDLoc(Op0),
8563 N->getVTList(), Extract0, Chain);
8564 return Extract0;
8565 }
8566 }
8567 }
8568 }
8569 return SDValue();
8570}
8571
8572SDValue SystemZTargetLowering::combineINT_TO_FP(
8573 SDNode *N, DAGCombinerInfo &DCI) const {
8574 if (DCI.Level != BeforeLegalizeTypes)
8575 return SDValue();
8576 SelectionDAG &DAG = DCI.DAG;
8577 LLVMContext &Ctx = *DAG.getContext();
8578 unsigned Opcode = N->getOpcode();
8579 EVT OutVT = N->getValueType(0);
8580 Type *OutLLVMTy = OutVT.getTypeForEVT(Ctx);
8581 SDValue Op = N->getOperand(0);
8582 unsigned OutScalarBits = OutLLVMTy->getScalarSizeInBits();
8583 unsigned InScalarBits = Op->getValueType(0).getScalarSizeInBits();
8584
8585 // Insert an extension before type-legalization to avoid scalarization, e.g.:
8586 // v2f64 = uint_to_fp v2i16
8587 // =>
8588 // v2f64 = uint_to_fp (v2i64 zero_extend v2i16)
8589 if (OutLLVMTy->isVectorTy() && OutScalarBits > InScalarBits &&
8590 OutScalarBits <= 64) {
8591 unsigned NumElts = cast<FixedVectorType>(OutLLVMTy)->getNumElements();
8592 EVT ExtVT = EVT::getVectorVT(
8593 Ctx, EVT::getIntegerVT(Ctx, OutLLVMTy->getScalarSizeInBits()), NumElts);
8594 unsigned ExtOpcode =
8596 SDValue ExtOp = DAG.getNode(ExtOpcode, SDLoc(N), ExtVT, Op);
8597 return DAG.getNode(Opcode, SDLoc(N), OutVT, ExtOp);
8598 }
8599 return SDValue();
8600}
8601
8602SDValue SystemZTargetLowering::combineFCOPYSIGN(
8603 SDNode *N, DAGCombinerInfo &DCI) const {
8604 SelectionDAG &DAG = DCI.DAG;
8605 EVT VT = N->getValueType(0);
8606 SDValue ValOp = N->getOperand(0);
8607 SDValue SignOp = N->getOperand(1);
8608
8609 // Remove the rounding which is not needed.
8610 if (SignOp.getOpcode() == ISD::FP_ROUND) {
8611 SDValue WideOp = SignOp.getOperand(0);
8612 return DAG.getNode(ISD::FCOPYSIGN, SDLoc(N), VT, ValOp, WideOp);
8613 }
8614
8615 return SDValue();
8616}
8617
8618SDValue SystemZTargetLowering::combineBSWAP(
8619 SDNode *N, DAGCombinerInfo &DCI) const {
8620 SelectionDAG &DAG = DCI.DAG;
8621 // Combine BSWAP (LOAD) into LRVH/LRV/LRVG/VLBR
8622 if (ISD::isNON_EXTLoad(N->getOperand(0).getNode()) &&
8623 N->getOperand(0).hasOneUse() &&
8624 canLoadStoreByteSwapped(N->getValueType(0))) {
8625 SDValue Load = N->getOperand(0);
8626 LoadSDNode *LD = cast<LoadSDNode>(Load);
8627
8628 // Create the byte-swapping load.
8629 SDValue Ops[] = {
8630 LD->getChain(), // Chain
8631 LD->getBasePtr() // Ptr
8632 };
8633 EVT LoadVT = N->getValueType(0);
8634 if (LoadVT == MVT::i16)
8635 LoadVT = MVT::i32;
8636 SDValue BSLoad =
8637 DAG.getMemIntrinsicNode(SystemZISD::LRV, SDLoc(N),
8638 DAG.getVTList(LoadVT, MVT::Other),
8639 Ops, LD->getMemoryVT(), LD->getMemOperand());
8640
8641 // If this is an i16 load, insert the truncate.
8642 SDValue ResVal = BSLoad;
8643 if (N->getValueType(0) == MVT::i16)
8644 ResVal = DAG.getNode(ISD::TRUNCATE, SDLoc(N), MVT::i16, BSLoad);
8645
8646 // First, combine the bswap away. This makes the value produced by the
8647 // load dead.
8648 DCI.CombineTo(N, ResVal);
8649
8650 // Next, combine the load away, we give it a bogus result value but a real
8651 // chain result. The result value is dead because the bswap is dead.
8652 DCI.CombineTo(Load.getNode(), ResVal, BSLoad.getValue(1));
8653
8654 // Return N so it doesn't get rechecked!
8655 return SDValue(N, 0);
8656 }
8657
8658 // Look through bitcasts that retain the number of vector elements.
8659 SDValue Op = N->getOperand(0);
8660 if (Op.getOpcode() == ISD::BITCAST &&
8661 Op.getValueType().isVector() &&
8662 Op.getOperand(0).getValueType().isVector() &&
8663 Op.getValueType().getVectorNumElements() ==
8664 Op.getOperand(0).getValueType().getVectorNumElements())
8665 Op = Op.getOperand(0);
8666
8667 // Push BSWAP into a vector insertion if at least one side then simplifies.
8668 if (Op.getOpcode() == ISD::INSERT_VECTOR_ELT && Op.hasOneUse()) {
8669 SDValue Vec = Op.getOperand(0);
8670 SDValue Elt = Op.getOperand(1);
8671 SDValue Idx = Op.getOperand(2);
8672
8674 Vec.getOpcode() == ISD::BSWAP || Vec.isUndef() ||
8676 Elt.getOpcode() == ISD::BSWAP || Elt.isUndef() ||
8677 (canLoadStoreByteSwapped(N->getValueType(0)) &&
8678 ISD::isNON_EXTLoad(Elt.getNode()) && Elt.hasOneUse())) {
8679 EVT VecVT = N->getValueType(0);
8680 EVT EltVT = N->getValueType(0).getVectorElementType();
8681 if (VecVT != Vec.getValueType()) {
8682 Vec = DAG.getNode(ISD::BITCAST, SDLoc(N), VecVT, Vec);
8683 DCI.AddToWorklist(Vec.getNode());
8684 }
8685 if (EltVT != Elt.getValueType()) {
8686 Elt = DAG.getNode(ISD::BITCAST, SDLoc(N), EltVT, Elt);
8687 DCI.AddToWorklist(Elt.getNode());
8688 }
8689 Vec = DAG.getNode(ISD::BSWAP, SDLoc(N), VecVT, Vec);
8690 DCI.AddToWorklist(Vec.getNode());
8691 Elt = DAG.getNode(ISD::BSWAP, SDLoc(N), EltVT, Elt);
8692 DCI.AddToWorklist(Elt.getNode());
8693 return DAG.getNode(ISD::INSERT_VECTOR_ELT, SDLoc(N), VecVT,
8694 Vec, Elt, Idx);
8695 }
8696 }
8697
8698 // Push BSWAP into a vector shuffle if at least one side then simplifies.
8699 ShuffleVectorSDNode *SV = dyn_cast<ShuffleVectorSDNode>(Op);
8700 if (SV && Op.hasOneUse()) {
8701 SDValue Op0 = Op.getOperand(0);
8702 SDValue Op1 = Op.getOperand(1);
8703
8705 Op0.getOpcode() == ISD::BSWAP || Op0.isUndef() ||
8707 Op1.getOpcode() == ISD::BSWAP || Op1.isUndef()) {
8708 EVT VecVT = N->getValueType(0);
8709 if (VecVT != Op0.getValueType()) {
8710 Op0 = DAG.getNode(ISD::BITCAST, SDLoc(N), VecVT, Op0);
8711 DCI.AddToWorklist(Op0.getNode());
8712 }
8713 if (VecVT != Op1.getValueType()) {
8714 Op1 = DAG.getNode(ISD::BITCAST, SDLoc(N), VecVT, Op1);
8715 DCI.AddToWorklist(Op1.getNode());
8716 }
8717 Op0 = DAG.getNode(ISD::BSWAP, SDLoc(N), VecVT, Op0);
8718 DCI.AddToWorklist(Op0.getNode());
8719 Op1 = DAG.getNode(ISD::BSWAP, SDLoc(N), VecVT, Op1);
8720 DCI.AddToWorklist(Op1.getNode());
8721 return DAG.getVectorShuffle(VecVT, SDLoc(N), Op0, Op1, SV->getMask());
8722 }
8723 }
8724
8725 return SDValue();
8726}
8727
8728SDValue SystemZTargetLowering::combineSETCC(
8729 SDNode *N, DAGCombinerInfo &DCI) const {
8730 SelectionDAG &DAG = DCI.DAG;
8731 const ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(2))->get();
8732 const SDValue LHS = N->getOperand(0);
8733 const SDValue RHS = N->getOperand(1);
8734 bool CmpNull = isNullConstant(RHS);
8735 bool CmpAllOnes = isAllOnesConstant(RHS);
8736 EVT VT = N->getValueType(0);
8737 SDLoc DL(N);
8738
8739 // Match icmp_eq/ne(bitcast(icmp(X,Y)),0/-1) reduction patterns, and
8740 // change the outer compare to a i128 compare. This will normally
8741 // allow the reduction to be recognized in adjustICmp128, and even if
8742 // not, the i128 compare will still generate better code.
8743 if ((CC == ISD::SETNE || CC == ISD::SETEQ) && (CmpNull || CmpAllOnes)) {
8745 if (Src.getOpcode() == ISD::SETCC &&
8746 Src.getValueType().isFixedLengthVector() &&
8747 Src.getValueType().getScalarType() == MVT::i1) {
8748 EVT CmpVT = Src.getOperand(0).getValueType();
8749 if (CmpVT.getSizeInBits() == 128) {
8750 EVT IntVT = CmpVT.changeVectorElementTypeToInteger();
8751 SDValue LHS =
8752 DAG.getBitcast(MVT::i128, DAG.getSExtOrTrunc(Src, DL, IntVT));
8753 SDValue RHS = CmpNull ? DAG.getConstant(0, DL, MVT::i128)
8754 : DAG.getAllOnesConstant(DL, MVT::i128);
8755 return DAG.getNode(ISD::SETCC, DL, VT, LHS, RHS, N->getOperand(2),
8756 N->getFlags());
8757 }
8758 }
8759 }
8760
8761 return SDValue();
8762}
8763
8764static std::pair<SDValue, int> findCCUse(const SDValue &Val,
8765 unsigned Depth = 0) {
8766 // Limit depth of potentially exponential walk.
8767 if (Depth > 5)
8768 return std::make_pair(SDValue(), SystemZ::CCMASK_NONE);
8769
8770 switch (Val.getOpcode()) {
8771 default:
8772 return std::make_pair(SDValue(), SystemZ::CCMASK_NONE);
8773 case SystemZISD::IPM:
8774 if (Val.getOperand(0).getOpcode() == SystemZISD::CLC ||
8775 Val.getOperand(0).getOpcode() == SystemZISD::STRCMP)
8776 return std::make_pair(Val.getOperand(0), SystemZ::CCMASK_ICMP);
8777 return std::make_pair(Val.getOperand(0), SystemZ::CCMASK_ANY);
8778 case SystemZISD::SELECT_CCMASK: {
8779 SDValue Op4CCReg = Val.getOperand(4);
8780 if (Op4CCReg.getOpcode() == SystemZISD::ICMP ||
8781 Op4CCReg.getOpcode() == SystemZISD::TM) {
8782 auto [OpCC, OpCCValid] = findCCUse(Op4CCReg.getOperand(0), Depth + 1);
8783 if (OpCC != SDValue())
8784 return std::make_pair(OpCC, OpCCValid);
8785 }
8786 auto *CCValid = dyn_cast<ConstantSDNode>(Val.getOperand(2));
8787 if (!CCValid)
8788 return std::make_pair(SDValue(), SystemZ::CCMASK_NONE);
8789 int CCValidVal = CCValid->getZExtValue();
8790 return std::make_pair(Op4CCReg, CCValidVal);
8791 }
8792 case ISD::ADD:
8793 case ISD::AND:
8794 case ISD::OR:
8795 case ISD::XOR:
8796 case ISD::SHL:
8797 case ISD::SRA:
8798 case ISD::SRL:
8799 auto [Op0CC, Op0CCValid] = findCCUse(Val.getOperand(0), Depth + 1);
8800 if (Op0CC != SDValue())
8801 return std::make_pair(Op0CC, Op0CCValid);
8802 return findCCUse(Val.getOperand(1), Depth + 1);
8803 }
8804}
8805
8806static bool combineCCMask(SDValue &CCReg, int &CCValid, int &CCMask,
8807 SelectionDAG &DAG);
8808
8810 SelectionDAG &DAG) {
8811 SDLoc DL(Val);
8812 auto Opcode = Val.getOpcode();
8813 switch (Opcode) {
8814 default:
8815 return {};
8816 case ISD::Constant:
8817 return {Val, Val, Val, Val};
8818 case SystemZISD::IPM: {
8819 SDValue IPMOp0 = Val.getOperand(0);
8820 if (IPMOp0 != CC)
8821 return {};
8822 SmallVector<SDValue, 4> ShiftedCCVals;
8823 for (auto CC : {0, 1, 2, 3})
8824 ShiftedCCVals.emplace_back(
8825 DAG.getConstant((CC << SystemZ::IPM_CC), DL, MVT::i32));
8826 return ShiftedCCVals;
8827 }
8828 case SystemZISD::SELECT_CCMASK: {
8829 SDValue TrueVal = Val.getOperand(0), FalseVal = Val.getOperand(1);
8830 auto *CCValid = dyn_cast<ConstantSDNode>(Val.getOperand(2));
8831 auto *CCMask = dyn_cast<ConstantSDNode>(Val.getOperand(3));
8832 if (!CCValid || !CCMask)
8833 return {};
8834
8835 int CCValidVal = CCValid->getZExtValue();
8836 int CCMaskVal = CCMask->getZExtValue();
8837 // Pruning search tree early - Moving CC test and combineCCMask ahead of
8838 // recursive call to simplifyAssumingCCVal.
8839 SDValue Op4CCReg = Val.getOperand(4);
8840 if (Op4CCReg != CC)
8841 combineCCMask(Op4CCReg, CCValidVal, CCMaskVal, DAG);
8842 if (Op4CCReg != CC)
8843 return {};
8844 const auto &&TrueSDVals = simplifyAssumingCCVal(TrueVal, CC, DAG);
8845 const auto &&FalseSDVals = simplifyAssumingCCVal(FalseVal, CC, DAG);
8846 if (TrueSDVals.empty() || FalseSDVals.empty())
8847 return {};
8848 SmallVector<SDValue, 4> MergedSDVals;
8849 for (auto &CCVal : {0, 1, 2, 3})
8850 MergedSDVals.emplace_back(((CCMaskVal & (1 << (3 - CCVal))) != 0)
8851 ? TrueSDVals[CCVal]
8852 : FalseSDVals[CCVal]);
8853 return MergedSDVals;
8854 }
8855 case ISD::ADD:
8856 case ISD::AND:
8857 case ISD::OR:
8858 case ISD::XOR:
8859 case ISD::SRA:
8860 // Avoid introducing CC spills (because ADD/AND/OR/XOR/SRA
8861 // would clobber CC).
8862 if (!Val.hasOneUse())
8863 return {};
8864 [[fallthrough]];
8865 case ISD::SHL:
8866 case ISD::SRL:
8867 SDValue Op0 = Val.getOperand(0), Op1 = Val.getOperand(1);
8868 const auto &&Op0SDVals = simplifyAssumingCCVal(Op0, CC, DAG);
8869 const auto &&Op1SDVals = simplifyAssumingCCVal(Op1, CC, DAG);
8870 if (Op0SDVals.empty() || Op1SDVals.empty())
8871 return {};
8872 SmallVector<SDValue, 4> BinaryOpSDVals;
8873 for (auto CCVal : {0, 1, 2, 3})
8874 BinaryOpSDVals.emplace_back(DAG.getNode(
8875 Opcode, DL, Val.getValueType(), Op0SDVals[CCVal], Op1SDVals[CCVal]));
8876 return BinaryOpSDVals;
8877 }
8878}
8879
8880static bool combineCCMask(SDValue &CCReg, int &CCValid, int &CCMask,
8881 SelectionDAG &DAG) {
8882 // We have a SELECT_CCMASK or BR_CCMASK comparing the condition code
8883 // set by the CCReg instruction using the CCValid / CCMask masks,
8884 // If the CCReg instruction is itself a ICMP / TM testing the condition
8885 // code set by some other instruction, see whether we can directly
8886 // use that condition code.
8887 auto *CCNode = CCReg.getNode();
8888 if (!CCNode)
8889 return false;
8890
8891 if (CCNode->getOpcode() == SystemZISD::TM) {
8892 if (CCValid != SystemZ::CCMASK_TM)
8893 return false;
8894 auto emulateTMCCMask = [](const SDValue &Op0Val, const SDValue &Op1Val) {
8895 auto *Op0Node = dyn_cast<ConstantSDNode>(Op0Val.getNode());
8896 auto *Op1Node = dyn_cast<ConstantSDNode>(Op1Val.getNode());
8897 if (!Op0Node || !Op1Node)
8898 return -1;
8899 auto Op0APVal = Op0Node->getAPIntValue();
8900 auto Op1APVal = Op1Node->getAPIntValue();
8901 auto Result = Op0APVal & Op1APVal;
8902 bool AllOnes = Result == Op1APVal;
8903 bool AllZeros = Result == 0;
8904 bool IsLeftMostBitSet = Result[Op1APVal.getActiveBits() - 1] != 0;
8905 return AllZeros ? 0 : AllOnes ? 3 : IsLeftMostBitSet ? 2 : 1;
8906 };
8907 SDValue Op0 = CCNode->getOperand(0);
8908 SDValue Op1 = CCNode->getOperand(1);
8909 auto [Op0CC, Op0CCValid] = findCCUse(Op0);
8910 if (Op0CC == SDValue())
8911 return false;
8912 const auto &&Op0SDVals = simplifyAssumingCCVal(Op0, Op0CC, DAG);
8913 const auto &&Op1SDVals = simplifyAssumingCCVal(Op1, Op0CC, DAG);
8914 if (Op0SDVals.empty() || Op1SDVals.empty())
8915 return false;
8916 int NewCCMask = 0;
8917 for (auto CC : {0, 1, 2, 3}) {
8918 auto CCVal = emulateTMCCMask(Op0SDVals[CC], Op1SDVals[CC]);
8919 if (CCVal < 0)
8920 return false;
8921 NewCCMask <<= 1;
8922 NewCCMask |= (CCMask & (1 << (3 - CCVal))) != 0;
8923 }
8924 NewCCMask &= Op0CCValid;
8925 CCReg = Op0CC;
8926 CCMask = NewCCMask;
8927 CCValid = Op0CCValid;
8928 return true;
8929 }
8930 if (CCNode->getOpcode() != SystemZISD::ICMP ||
8931 CCValid != SystemZ::CCMASK_ICMP)
8932 return false;
8933
8934 SDValue CmpOp0 = CCNode->getOperand(0);
8935 SDValue CmpOp1 = CCNode->getOperand(1);
8936 SDValue CmpOp2 = CCNode->getOperand(2);
8937 auto [Op0CC, Op0CCValid] = findCCUse(CmpOp0);
8938 if (Op0CC != SDValue()) {
8939 const auto &&Op0SDVals = simplifyAssumingCCVal(CmpOp0, Op0CC, DAG);
8940 const auto &&Op1SDVals = simplifyAssumingCCVal(CmpOp1, Op0CC, DAG);
8941 if (Op0SDVals.empty() || Op1SDVals.empty())
8942 return false;
8943
8944 auto *CmpType = dyn_cast<ConstantSDNode>(CmpOp2);
8945 auto CmpTypeVal = CmpType->getZExtValue();
8946 const auto compareCCSigned = [&CmpTypeVal](const SDValue &Op0Val,
8947 const SDValue &Op1Val) {
8948 auto *Op0Node = dyn_cast<ConstantSDNode>(Op0Val.getNode());
8949 auto *Op1Node = dyn_cast<ConstantSDNode>(Op1Val.getNode());
8950 if (!Op0Node || !Op1Node)
8951 return -1;
8952 auto Op0APVal = Op0Node->getAPIntValue();
8953 auto Op1APVal = Op1Node->getAPIntValue();
8954 if (CmpTypeVal == SystemZICMP::SignedOnly)
8955 return Op0APVal == Op1APVal ? 0 : Op0APVal.slt(Op1APVal) ? 1 : 2;
8956 return Op0APVal == Op1APVal ? 0 : Op0APVal.ult(Op1APVal) ? 1 : 2;
8957 };
8958 int NewCCMask = 0;
8959 for (auto CC : {0, 1, 2, 3}) {
8960 auto CCVal = compareCCSigned(Op0SDVals[CC], Op1SDVals[CC]);
8961 if (CCVal < 0)
8962 return false;
8963 NewCCMask <<= 1;
8964 NewCCMask |= (CCMask & (1 << (3 - CCVal))) != 0;
8965 }
8966 NewCCMask &= Op0CCValid;
8967 CCMask = NewCCMask;
8968 CCReg = Op0CC;
8969 CCValid = Op0CCValid;
8970 return true;
8971 }
8972
8973 return false;
8974}
8975
8976// Merging versus split in multiple branches cost.
8979 const Value *Lhs,
8980 const Value *Rhs,
8981 const Function *) const {
8982 const auto isFlagOutOpCC = [](const Value *V) {
8983 using namespace llvm::PatternMatch;
8984 const Value *RHSVal;
8985 const APInt *RHSC;
8986 if (const auto *I = dyn_cast<Instruction>(V)) {
8987 // PatternMatch.h provides concise tree-based pattern match of llvm IR.
8988 if (match(I->getOperand(0), m_And(m_Value(RHSVal), m_APInt(RHSC))) ||
8989 match(I, m_Cmp(m_Value(RHSVal), m_APInt(RHSC)))) {
8990 if (const auto *CB = dyn_cast<CallBase>(RHSVal)) {
8991 if (CB->isInlineAsm()) {
8992 const InlineAsm *IA = cast<InlineAsm>(CB->getCalledOperand());
8993 return IA && IA->getConstraintString().contains("{@cc}");
8994 }
8995 }
8996 }
8997 }
8998 return false;
8999 };
9000 // Pattern (ICmp %asm) or (ICmp (And %asm)).
9001 // Cost of longest dependency chain (ICmp, And) is 2. CostThreshold or
9002 // BaseCost can be set >=2. If cost of instruction <= CostThreshold
9003 // conditionals will be merged or else conditionals will be split.
9004 if (isFlagOutOpCC(Lhs) && isFlagOutOpCC(Rhs))
9005 return {3, 0, -1};
9006 // Default.
9007 return {-1, -1, -1};
9008}
9009
9010SDValue SystemZTargetLowering::combineBR_CCMASK(SDNode *N,
9011 DAGCombinerInfo &DCI) const {
9012 SelectionDAG &DAG = DCI.DAG;
9013
9014 // Combine BR_CCMASK (ICMP (SELECT_CCMASK)) into a single BR_CCMASK.
9015 auto *CCValid = dyn_cast<ConstantSDNode>(N->getOperand(1));
9016 auto *CCMask = dyn_cast<ConstantSDNode>(N->getOperand(2));
9017 if (!CCValid || !CCMask)
9018 return SDValue();
9019
9020 int CCValidVal = CCValid->getZExtValue();
9021 int CCMaskVal = CCMask->getZExtValue();
9022 SDValue Chain = N->getOperand(0);
9023 SDValue CCReg = N->getOperand(4);
9024 // If combineCMask was able to merge or simplify ccvalid or ccmask, re-emit
9025 // the modified BR_CCMASK with the new values.
9026 // In order to avoid conditional branches with full or empty cc masks, do not
9027 // do this if ccmask is 0 or equal to ccvalid.
9028 if (combineCCMask(CCReg, CCValidVal, CCMaskVal, DAG) && CCMaskVal != 0 &&
9029 CCMaskVal != CCValidVal)
9030 return DAG.getNode(SystemZISD::BR_CCMASK, SDLoc(N), N->getValueType(0),
9031 Chain,
9032 DAG.getTargetConstant(CCValidVal, SDLoc(N), MVT::i32),
9033 DAG.getTargetConstant(CCMaskVal, SDLoc(N), MVT::i32),
9034 N->getOperand(3), CCReg);
9035 return SDValue();
9036}
9037
9038SDValue SystemZTargetLowering::combineSELECT_CCMASK(
9039 SDNode *N, DAGCombinerInfo &DCI) const {
9040 SelectionDAG &DAG = DCI.DAG;
9041
9042 // Combine SELECT_CCMASK (ICMP (SELECT_CCMASK)) into a single SELECT_CCMASK.
9043 auto *CCValid = dyn_cast<ConstantSDNode>(N->getOperand(2));
9044 auto *CCMask = dyn_cast<ConstantSDNode>(N->getOperand(3));
9045 if (!CCValid || !CCMask)
9046 return SDValue();
9047
9048 int CCValidVal = CCValid->getZExtValue();
9049 int CCMaskVal = CCMask->getZExtValue();
9050 SDValue CCReg = N->getOperand(4);
9051
9052 bool IsCombinedCCReg = combineCCMask(CCReg, CCValidVal, CCMaskVal, DAG);
9053
9054 // Populate SDVals vector for each condition code ccval for given Val, which
9055 // can again be another nested select_ccmask with the same CC.
9056 const auto constructCCSDValsFromSELECT = [&CCReg](SDValue &Val) {
9057 if (Val.getOpcode() == SystemZISD::SELECT_CCMASK) {
9059 if (Val.getOperand(4) != CCReg)
9060 return SmallVector<SDValue, 4>{};
9061 SDValue TrueVal = Val.getOperand(0), FalseVal = Val.getOperand(1);
9062 auto *CCMask = dyn_cast<ConstantSDNode>(Val.getOperand(3));
9063 if (!CCMask)
9064 return SmallVector<SDValue, 4>{};
9065
9066 int CCMaskVal = CCMask->getZExtValue();
9067 for (auto &CC : {0, 1, 2, 3})
9068 Res.emplace_back(((CCMaskVal & (1 << (3 - CC))) != 0) ? TrueVal
9069 : FalseVal);
9070 return Res;
9071 }
9072 return SmallVector<SDValue, 4>{Val, Val, Val, Val};
9073 };
9074 // Attempting to optimize TrueVal/FalseVal in outermost select_ccmask either
9075 // with CCReg found by combineCCMask or original CCReg.
9076 SDValue TrueVal = N->getOperand(0);
9077 SDValue FalseVal = N->getOperand(1);
9078 auto &&TrueSDVals = simplifyAssumingCCVal(TrueVal, CCReg, DAG);
9079 auto &&FalseSDVals = simplifyAssumingCCVal(FalseVal, CCReg, DAG);
9080 // TrueSDVals/FalseSDVals might be empty in case of non-constant
9081 // TrueVal/FalseVal for select_ccmask, which can not be optimized further.
9082 if (TrueSDVals.empty())
9083 TrueSDVals = constructCCSDValsFromSELECT(TrueVal);
9084 if (FalseSDVals.empty())
9085 FalseSDVals = constructCCSDValsFromSELECT(FalseVal);
9086 if (!TrueSDVals.empty() && !FalseSDVals.empty()) {
9087 SmallSet<SDValue, 4> MergedSDValsSet;
9088 // Ignoring CC values outside CCValiid.
9089 for (auto CC : {0, 1, 2, 3}) {
9090 if ((CCValidVal & ((1 << (3 - CC)))) != 0)
9091 MergedSDValsSet.insert(((CCMaskVal & (1 << (3 - CC))) != 0)
9092 ? TrueSDVals[CC]
9093 : FalseSDVals[CC]);
9094 }
9095 if (MergedSDValsSet.size() == 1)
9096 return *MergedSDValsSet.begin();
9097 if (MergedSDValsSet.size() == 2) {
9098 auto BeginIt = MergedSDValsSet.begin();
9099 SDValue NewTrueVal = *BeginIt, NewFalseVal = *next(BeginIt);
9100 if (NewTrueVal == FalseVal || NewFalseVal == TrueVal)
9101 std::swap(NewTrueVal, NewFalseVal);
9102 int NewCCMask = 0;
9103 for (auto CC : {0, 1, 2, 3}) {
9104 NewCCMask <<= 1;
9105 NewCCMask |= ((CCMaskVal & (1 << (3 - CC))) != 0)
9106 ? (TrueSDVals[CC] == NewTrueVal)
9107 : (FalseSDVals[CC] == NewTrueVal);
9108 }
9109 CCMaskVal = NewCCMask;
9110 CCMaskVal &= CCValidVal;
9111 TrueVal = NewTrueVal;
9112 FalseVal = NewFalseVal;
9113 IsCombinedCCReg = true;
9114 }
9115 }
9116 // If the condition is trivially false or trivially true after
9117 // combineCCMask, just collapse this SELECT_CCMASK to the indicated value
9118 // (possibly modified by constructCCSDValsFromSELECT).
9119 if (CCMaskVal == 0)
9120 return FalseVal;
9121 if (CCMaskVal == CCValidVal)
9122 return TrueVal;
9123
9124 if (IsCombinedCCReg)
9125 return DAG.getNode(
9126 SystemZISD::SELECT_CCMASK, SDLoc(N), N->getValueType(0), TrueVal,
9127 FalseVal, DAG.getTargetConstant(CCValidVal, SDLoc(N), MVT::i32),
9128 DAG.getTargetConstant(CCMaskVal, SDLoc(N), MVT::i32), CCReg);
9129
9130 return SDValue();
9131}
9132
9133SDValue SystemZTargetLowering::combineGET_CCMASK(
9134 SDNode *N, DAGCombinerInfo &DCI) const {
9135
9136 // Optimize away GET_CCMASK (SELECT_CCMASK) if the CC masks are compatible
9137 auto *CCValid = dyn_cast<ConstantSDNode>(N->getOperand(1));
9138 auto *CCMask = dyn_cast<ConstantSDNode>(N->getOperand(2));
9139 if (!CCValid || !CCMask)
9140 return SDValue();
9141 int CCValidVal = CCValid->getZExtValue();
9142 int CCMaskVal = CCMask->getZExtValue();
9143
9144 SDValue Select = N->getOperand(0);
9145 if (Select->getOpcode() == ISD::TRUNCATE)
9146 Select = Select->getOperand(0);
9147 if (Select->getOpcode() != SystemZISD::SELECT_CCMASK)
9148 return SDValue();
9149
9150 auto *SelectCCValid = dyn_cast<ConstantSDNode>(Select->getOperand(2));
9151 auto *SelectCCMask = dyn_cast<ConstantSDNode>(Select->getOperand(3));
9152 if (!SelectCCValid || !SelectCCMask)
9153 return SDValue();
9154 int SelectCCValidVal = SelectCCValid->getZExtValue();
9155 int SelectCCMaskVal = SelectCCMask->getZExtValue();
9156
9157 auto *TrueVal = dyn_cast<ConstantSDNode>(Select->getOperand(0));
9158 auto *FalseVal = dyn_cast<ConstantSDNode>(Select->getOperand(1));
9159 if (!TrueVal || !FalseVal)
9160 return SDValue();
9161 if (TrueVal->getZExtValue() == 1 && FalseVal->getZExtValue() == 0)
9162 ;
9163 else if (TrueVal->getZExtValue() == 0 && FalseVal->getZExtValue() == 1)
9164 SelectCCMaskVal ^= SelectCCValidVal;
9165 else
9166 return SDValue();
9167
9168 if (SelectCCValidVal & ~CCValidVal)
9169 return SDValue();
9170 if (SelectCCMaskVal != (CCMaskVal & SelectCCValidVal))
9171 return SDValue();
9172
9173 return Select->getOperand(4);
9174}
9175
9176SDValue SystemZTargetLowering::combineIntDIVREM(
9177 SDNode *N, DAGCombinerInfo &DCI) const {
9178 SelectionDAG &DAG = DCI.DAG;
9179 EVT VT = N->getValueType(0);
9180 // In the case where the divisor is a vector of constants a cheaper
9181 // sequence of instructions can replace the divide. BuildSDIV is called to
9182 // do this during DAG combining, but it only succeeds when it can build a
9183 // multiplication node. The only option for SystemZ is ISD::SMUL_LOHI, and
9184 // since it is not Legal but Custom it can only happen before
9185 // legalization. Therefore we must scalarize this early before Combine
9186 // 1. For widened vectors, this is already the result of type legalization.
9187 if (DCI.Level == BeforeLegalizeTypes && VT.isVector() && isTypeLegal(VT) &&
9188 DAG.isConstantIntBuildVectorOrConstantInt(N->getOperand(1)))
9189 return DAG.UnrollVectorOp(N);
9190 return SDValue();
9191}
9192
9193
9194// Transform a right shift of a multiply-and-add into a multiply-and-add-high.
9195// This is closely modeled after the common-code combineShiftToMULH.
9196SDValue SystemZTargetLowering::combineShiftToMulAddHigh(
9197 SDNode *N, DAGCombinerInfo &DCI) const {
9198 SelectionDAG &DAG = DCI.DAG;
9199 SDLoc DL(N);
9200
9201 assert((N->getOpcode() == ISD::SRL || N->getOpcode() == ISD::SRA) &&
9202 "SRL or SRA node is required here!");
9203
9204 if (!Subtarget.hasVector())
9205 return SDValue();
9206
9207 // Check the shift amount. Proceed with the transformation if the shift
9208 // amount is constant.
9209 ConstantSDNode *ShiftAmtSrc = isConstOrConstSplat(N->getOperand(1));
9210 if (!ShiftAmtSrc)
9211 return SDValue();
9212
9213 // The operation feeding into the shift must be an add.
9214 SDValue ShiftOperand = N->getOperand(0);
9215 if (ShiftOperand.getOpcode() != ISD::ADD)
9216 return SDValue();
9217
9218 // One operand of the add must be a multiply.
9219 SDValue MulOp = ShiftOperand.getOperand(0);
9220 SDValue AddOp = ShiftOperand.getOperand(1);
9221 if (MulOp.getOpcode() != ISD::MUL) {
9222 if (AddOp.getOpcode() != ISD::MUL)
9223 return SDValue();
9224 std::swap(MulOp, AddOp);
9225 }
9226
9227 // All operands must be equivalent extend nodes.
9228 SDValue LeftOp = MulOp.getOperand(0);
9229 SDValue RightOp = MulOp.getOperand(1);
9230
9231 bool IsSignExt = LeftOp.getOpcode() == ISD::SIGN_EXTEND;
9232 bool IsZeroExt = LeftOp.getOpcode() == ISD::ZERO_EXTEND;
9233
9234 if (!IsSignExt && !IsZeroExt)
9235 return SDValue();
9236
9237 EVT NarrowVT = LeftOp.getOperand(0).getValueType();
9238 unsigned NarrowVTSize = NarrowVT.getScalarSizeInBits();
9239
9240 SDValue MulhRightOp;
9241 if (ConstantSDNode *Constant = isConstOrConstSplat(RightOp)) {
9242 unsigned ActiveBits = IsSignExt
9243 ? Constant->getAPIntValue().getSignificantBits()
9244 : Constant->getAPIntValue().getActiveBits();
9245 if (ActiveBits > NarrowVTSize)
9246 return SDValue();
9247 MulhRightOp = DAG.getConstant(
9248 Constant->getAPIntValue().trunc(NarrowVT.getScalarSizeInBits()), DL,
9249 NarrowVT);
9250 } else {
9251 if (LeftOp.getOpcode() != RightOp.getOpcode())
9252 return SDValue();
9253 // Check that the two extend nodes are the same type.
9254 if (NarrowVT != RightOp.getOperand(0).getValueType())
9255 return SDValue();
9256 MulhRightOp = RightOp.getOperand(0);
9257 }
9258
9259 SDValue MulhAddOp;
9260 if (ConstantSDNode *Constant = isConstOrConstSplat(AddOp)) {
9261 unsigned ActiveBits = IsSignExt
9262 ? Constant->getAPIntValue().getSignificantBits()
9263 : Constant->getAPIntValue().getActiveBits();
9264 if (ActiveBits > NarrowVTSize)
9265 return SDValue();
9266 MulhAddOp = DAG.getConstant(
9267 Constant->getAPIntValue().trunc(NarrowVT.getScalarSizeInBits()), DL,
9268 NarrowVT);
9269 } else {
9270 if (LeftOp.getOpcode() != AddOp.getOpcode())
9271 return SDValue();
9272 // Check that the two extend nodes are the same type.
9273 if (NarrowVT != AddOp.getOperand(0).getValueType())
9274 return SDValue();
9275 MulhAddOp = AddOp.getOperand(0);
9276 }
9277
9278 EVT WideVT = LeftOp.getValueType();
9279 // Proceed with the transformation if the wide types match.
9280 assert((WideVT == RightOp.getValueType()) &&
9281 "Cannot have a multiply node with two different operand types.");
9282 assert((WideVT == AddOp.getValueType()) &&
9283 "Cannot have an add node with two different operand types.");
9284
9285 // Proceed with the transformation if the wide type is twice as large
9286 // as the narrow type.
9287 if (WideVT.getScalarSizeInBits() != 2 * NarrowVTSize)
9288 return SDValue();
9289
9290 // Check the shift amount with the narrow type size.
9291 // Proceed with the transformation if the shift amount is the width
9292 // of the narrow type.
9293 unsigned ShiftAmt = ShiftAmtSrc->getZExtValue();
9294 if (ShiftAmt != NarrowVTSize)
9295 return SDValue();
9296
9297 // Proceed if we support the multiply-and-add-high operation.
9298 if (!(NarrowVT == MVT::v16i8 || NarrowVT == MVT::v8i16 ||
9299 NarrowVT == MVT::v4i32 ||
9300 (Subtarget.hasVectorEnhancements3() &&
9301 (NarrowVT == MVT::v2i64 || NarrowVT == MVT::i128))))
9302 return SDValue();
9303
9304 // Emit the VMAH (signed) or VMALH (unsigned) operation.
9305 SDValue Result = DAG.getNode(IsSignExt ? SystemZISD::VMAH : SystemZISD::VMALH,
9306 DL, NarrowVT, LeftOp.getOperand(0),
9307 MulhRightOp, MulhAddOp);
9308 bool IsSigned = N->getOpcode() == ISD::SRA;
9309 return DAG.getExtOrTrunc(IsSigned, Result, DL, WideVT);
9310}
9311
9312// Op is an operand of a multiplication. Check whether this can be folded
9313// into an even/odd widening operation; if so, return the opcode to be used
9314// and update Op to the appropriate sub-operand. Note that the caller must
9315// verify that *both* operands of the multiplication support the operation.
9317 const SystemZSubtarget &Subtarget,
9318 SDValue &Op) {
9319 EVT VT = Op.getValueType();
9320
9321 // Check for (sign/zero_extend_vector_inreg (vector_shuffle)) corresponding
9322 // to selecting the even or odd vector elements.
9323 if (VT.isVector() && DAG.getTargetLoweringInfo().isTypeLegal(VT) &&
9324 (Op.getOpcode() == ISD::SIGN_EXTEND_VECTOR_INREG ||
9325 Op.getOpcode() == ISD::ZERO_EXTEND_VECTOR_INREG)) {
9326 bool IsSigned = Op.getOpcode() == ISD::SIGN_EXTEND_VECTOR_INREG;
9327 unsigned NumElts = VT.getVectorNumElements();
9328 Op = Op.getOperand(0);
9329 if (Op.getValueType().getVectorNumElements() == 2 * NumElts &&
9330 Op.getOpcode() == ISD::VECTOR_SHUFFLE) {
9332 ArrayRef<int> ShuffleMask = SVN->getMask();
9333 bool CanUseEven = true, CanUseOdd = true;
9334 for (unsigned Elt = 0; Elt < NumElts; Elt++) {
9335 if (ShuffleMask[Elt] == -1)
9336 continue;
9337 if (unsigned(ShuffleMask[Elt]) != 2 * Elt)
9338 CanUseEven = false;
9339 if (unsigned(ShuffleMask[Elt]) != 2 * Elt + 1)
9340 CanUseOdd = false;
9341 }
9342 Op = Op.getOperand(0);
9343 if (CanUseEven)
9344 return IsSigned ? SystemZISD::VME : SystemZISD::VMLE;
9345 if (CanUseOdd)
9346 return IsSigned ? SystemZISD::VMO : SystemZISD::VMLO;
9347 }
9348 }
9349
9350 // For z17, we can also support the v2i64->i128 case, which looks like
9351 // (sign/zero_extend (extract_vector_elt X 0/1))
9352 if (VT == MVT::i128 && Subtarget.hasVectorEnhancements3() &&
9353 (Op.getOpcode() == ISD::SIGN_EXTEND ||
9354 Op.getOpcode() == ISD::ZERO_EXTEND)) {
9355 bool IsSigned = Op.getOpcode() == ISD::SIGN_EXTEND;
9356 Op = Op.getOperand(0);
9357 if (Op.getOpcode() == ISD::EXTRACT_VECTOR_ELT &&
9358 Op.getOperand(0).getValueType() == MVT::v2i64 &&
9359 Op.getOperand(1).getOpcode() == ISD::Constant) {
9360 unsigned Elem = Op.getConstantOperandVal(1);
9361 Op = Op.getOperand(0);
9362 if (Elem == 0)
9363 return IsSigned ? SystemZISD::VME : SystemZISD::VMLE;
9364 if (Elem == 1)
9365 return IsSigned ? SystemZISD::VMO : SystemZISD::VMLO;
9366 }
9367 }
9368
9369 return 0;
9370}
9371
9372SDValue SystemZTargetLowering::combineMUL(
9373 SDNode *N, DAGCombinerInfo &DCI) const {
9374 SelectionDAG &DAG = DCI.DAG;
9375
9376 // Detect even/odd widening multiplication.
9377 SDValue Op0 = N->getOperand(0);
9378 SDValue Op1 = N->getOperand(1);
9379 unsigned OpcodeCand0 = detectEvenOddMultiplyOperand(DAG, Subtarget, Op0);
9380 unsigned OpcodeCand1 = detectEvenOddMultiplyOperand(DAG, Subtarget, Op1);
9381 if (OpcodeCand0 && OpcodeCand0 == OpcodeCand1)
9382 return DAG.getNode(OpcodeCand0, SDLoc(N), N->getValueType(0), Op0, Op1);
9383
9384 return SDValue();
9385}
9386
9387SDValue SystemZTargetLowering::combineINTRINSIC(
9388 SDNode *N, DAGCombinerInfo &DCI) const {
9389 SelectionDAG &DAG = DCI.DAG;
9390
9391 unsigned Id = N->getConstantOperandVal(1);
9392 switch (Id) {
9393 // VECTOR LOAD (RIGHTMOST) WITH LENGTH with a length operand of 15
9394 // or larger is simply a vector load.
9395 case Intrinsic::s390_vll:
9396 case Intrinsic::s390_vlrl:
9397 if (auto *C = dyn_cast<ConstantSDNode>(N->getOperand(2)))
9398 if (C->getZExtValue() >= 15)
9399 return DAG.getLoad(N->getValueType(0), SDLoc(N), N->getOperand(0),
9400 N->getOperand(3), MachinePointerInfo());
9401 break;
9402 // Likewise for VECTOR STORE (RIGHTMOST) WITH LENGTH.
9403 case Intrinsic::s390_vstl:
9404 case Intrinsic::s390_vstrl:
9405 if (auto *C = dyn_cast<ConstantSDNode>(N->getOperand(3)))
9406 if (C->getZExtValue() >= 15)
9407 return DAG.getStore(N->getOperand(0), SDLoc(N), N->getOperand(2),
9408 N->getOperand(4), MachinePointerInfo());
9409 break;
9410 }
9411
9412 return SDValue();
9413}
9414
9415SDValue SystemZTargetLowering::unwrapAddress(SDValue N) const {
9416 if (N->getOpcode() == SystemZISD::PCREL_WRAPPER)
9417 return N->getOperand(0);
9418 return N;
9419}
9420
9422 DAGCombinerInfo &DCI) const {
9423 switch(N->getOpcode()) {
9424 default: break;
9425 case ISD::ZERO_EXTEND: return combineZERO_EXTEND(N, DCI);
9426 case ISD::SIGN_EXTEND: return combineSIGN_EXTEND(N, DCI);
9427 case ISD::SIGN_EXTEND_INREG: return combineSIGN_EXTEND_INREG(N, DCI);
9428 case SystemZISD::MERGE_HIGH:
9429 case SystemZISD::MERGE_LOW: return combineMERGE(N, DCI);
9430 case ISD::LOAD: return combineLOAD(N, DCI);
9431 case ISD::STORE: return combineSTORE(N, DCI);
9432 case ISD::VECTOR_SHUFFLE: return combineVECTOR_SHUFFLE(N, DCI);
9433 case ISD::EXTRACT_VECTOR_ELT: return combineEXTRACT_VECTOR_ELT(N, DCI);
9434 case SystemZISD::JOIN_DWORDS: return combineJOIN_DWORDS(N, DCI);
9436 case ISD::FP_ROUND: return combineFP_ROUND(N, DCI);
9438 case ISD::FP_EXTEND: return combineFP_EXTEND(N, DCI);
9439 case ISD::SINT_TO_FP:
9440 case ISD::UINT_TO_FP: return combineINT_TO_FP(N, DCI);
9441 case ISD::FCOPYSIGN: return combineFCOPYSIGN(N, DCI);
9442 case ISD::BSWAP: return combineBSWAP(N, DCI);
9443 case ISD::SETCC: return combineSETCC(N, DCI);
9444 case SystemZISD::BR_CCMASK: return combineBR_CCMASK(N, DCI);
9445 case SystemZISD::SELECT_CCMASK: return combineSELECT_CCMASK(N, DCI);
9446 case SystemZISD::GET_CCMASK: return combineGET_CCMASK(N, DCI);
9447 case ISD::SRL:
9448 case ISD::SRA: return combineShiftToMulAddHigh(N, DCI);
9449 case ISD::MUL: return combineMUL(N, DCI);
9450 case ISD::SDIV:
9451 case ISD::UDIV:
9452 case ISD::SREM:
9453 case ISD::UREM: return combineIntDIVREM(N, DCI);
9455 case ISD::INTRINSIC_VOID: return combineINTRINSIC(N, DCI);
9456 }
9457
9458 return SDValue();
9459}
9460
9461// Return the demanded elements for the OpNo source operand of Op. DemandedElts
9462// are for Op.
9463static APInt getDemandedSrcElements(SDValue Op, const APInt &DemandedElts,
9464 unsigned OpNo) {
9465 EVT VT = Op.getValueType();
9466 unsigned NumElts = (VT.isVector() ? VT.getVectorNumElements() : 1);
9467 APInt SrcDemE;
9468 unsigned Opcode = Op.getOpcode();
9469 if (Opcode == ISD::INTRINSIC_WO_CHAIN) {
9470 unsigned Id = Op.getConstantOperandVal(0);
9471 switch (Id) {
9472 case Intrinsic::s390_vpksh: // PACKS
9473 case Intrinsic::s390_vpksf:
9474 case Intrinsic::s390_vpksg:
9475 case Intrinsic::s390_vpkshs: // PACKS_CC
9476 case Intrinsic::s390_vpksfs:
9477 case Intrinsic::s390_vpksgs:
9478 case Intrinsic::s390_vpklsh: // PACKLS
9479 case Intrinsic::s390_vpklsf:
9480 case Intrinsic::s390_vpklsg:
9481 case Intrinsic::s390_vpklshs: // PACKLS_CC
9482 case Intrinsic::s390_vpklsfs:
9483 case Intrinsic::s390_vpklsgs:
9484 // VECTOR PACK truncates the elements of two source vectors into one.
9485 SrcDemE = DemandedElts;
9486 if (OpNo == 2)
9487 SrcDemE.lshrInPlace(NumElts / 2);
9488 SrcDemE = SrcDemE.trunc(NumElts / 2);
9489 break;
9490 // VECTOR UNPACK extends half the elements of the source vector.
9491 case Intrinsic::s390_vuphb: // VECTOR UNPACK HIGH
9492 case Intrinsic::s390_vuphh:
9493 case Intrinsic::s390_vuphf:
9494 case Intrinsic::s390_vuplhb: // VECTOR UNPACK LOGICAL HIGH
9495 case Intrinsic::s390_vuplhh:
9496 case Intrinsic::s390_vuplhf:
9497 SrcDemE = APInt(NumElts * 2, 0);
9498 SrcDemE.insertBits(DemandedElts, 0);
9499 break;
9500 case Intrinsic::s390_vuplb: // VECTOR UNPACK LOW
9501 case Intrinsic::s390_vuplhw:
9502 case Intrinsic::s390_vuplf:
9503 case Intrinsic::s390_vupllb: // VECTOR UNPACK LOGICAL LOW
9504 case Intrinsic::s390_vupllh:
9505 case Intrinsic::s390_vupllf:
9506 SrcDemE = APInt(NumElts * 2, 0);
9507 SrcDemE.insertBits(DemandedElts, NumElts);
9508 break;
9509 case Intrinsic::s390_vpdi: {
9510 // VECTOR PERMUTE DWORD IMMEDIATE selects one element from each source.
9511 SrcDemE = APInt(NumElts, 0);
9512 if (!DemandedElts[OpNo - 1])
9513 break;
9514 unsigned Mask = Op.getConstantOperandVal(3);
9515 unsigned MaskBit = ((OpNo - 1) ? 1 : 4);
9516 // Demand input element 0 or 1, given by the mask bit value.
9517 SrcDemE.setBit((Mask & MaskBit)? 1 : 0);
9518 break;
9519 }
9520 case Intrinsic::s390_vsldb: {
9521 // VECTOR SHIFT LEFT DOUBLE BY BYTE
9522 assert(VT == MVT::v16i8 && "Unexpected type.");
9523 unsigned FirstIdx = Op.getConstantOperandVal(3);
9524 assert (FirstIdx > 0 && FirstIdx < 16 && "Unused operand.");
9525 unsigned NumSrc0Els = 16 - FirstIdx;
9526 SrcDemE = APInt(NumElts, 0);
9527 if (OpNo == 1) {
9528 APInt DemEls = DemandedElts.trunc(NumSrc0Els);
9529 SrcDemE.insertBits(DemEls, FirstIdx);
9530 } else {
9531 APInt DemEls = DemandedElts.lshr(NumSrc0Els);
9532 SrcDemE.insertBits(DemEls, 0);
9533 }
9534 break;
9535 }
9536 case Intrinsic::s390_vperm:
9537 SrcDemE = APInt::getAllOnes(NumElts);
9538 break;
9539 default:
9540 llvm_unreachable("Unhandled intrinsic.");
9541 break;
9542 }
9543 } else {
9544 switch (Opcode) {
9545 case SystemZISD::JOIN_DWORDS:
9546 // Scalar operand.
9547 SrcDemE = APInt(1, 1);
9548 break;
9549 case SystemZISD::SELECT_CCMASK:
9550 SrcDemE = DemandedElts;
9551 break;
9552 default:
9553 llvm_unreachable("Unhandled opcode.");
9554 break;
9555 }
9556 }
9557 return SrcDemE;
9558}
9559
9561 const APInt &DemandedElts,
9562 const SelectionDAG &DAG, unsigned Depth,
9563 unsigned OpNo) {
9564 APInt Src0DemE = getDemandedSrcElements(Op, DemandedElts, OpNo);
9565 APInt Src1DemE = getDemandedSrcElements(Op, DemandedElts, OpNo + 1);
9566 KnownBits LHSKnown =
9567 DAG.computeKnownBits(Op.getOperand(OpNo), Src0DemE, Depth + 1);
9568 KnownBits RHSKnown =
9569 DAG.computeKnownBits(Op.getOperand(OpNo + 1), Src1DemE, Depth + 1);
9570 Known = LHSKnown.intersectWith(RHSKnown);
9571}
9572
9573void
9576 const APInt &DemandedElts,
9577 const SelectionDAG &DAG,
9578 unsigned Depth) const {
9579 Known.resetAll();
9580
9581 // Intrinsic CC result is returned in the two low bits.
9582 unsigned Tmp0, Tmp1; // not used
9583 if (Op.getResNo() == 1 && isIntrinsicWithCC(Op, Tmp0, Tmp1)) {
9584 Known.Zero.setBitsFrom(2);
9585 return;
9586 }
9587 EVT VT = Op.getValueType();
9588 if (Op.getResNo() != 0 || VT == MVT::Untyped)
9589 return;
9590 assert (Known.getBitWidth() == VT.getScalarSizeInBits() &&
9591 "KnownBits does not match VT in bitwidth");
9592 assert ((!VT.isVector() ||
9593 (DemandedElts.getBitWidth() == VT.getVectorNumElements())) &&
9594 "DemandedElts does not match VT number of elements");
9595 unsigned BitWidth = Known.getBitWidth();
9596 unsigned Opcode = Op.getOpcode();
9597 if (Opcode == ISD::INTRINSIC_WO_CHAIN) {
9598 bool IsLogical = false;
9599 unsigned Id = Op.getConstantOperandVal(0);
9600 switch (Id) {
9601 case Intrinsic::s390_vpksh: // PACKS
9602 case Intrinsic::s390_vpksf:
9603 case Intrinsic::s390_vpksg:
9604 case Intrinsic::s390_vpkshs: // PACKS_CC
9605 case Intrinsic::s390_vpksfs:
9606 case Intrinsic::s390_vpksgs:
9607 case Intrinsic::s390_vpklsh: // PACKLS
9608 case Intrinsic::s390_vpklsf:
9609 case Intrinsic::s390_vpklsg:
9610 case Intrinsic::s390_vpklshs: // PACKLS_CC
9611 case Intrinsic::s390_vpklsfs:
9612 case Intrinsic::s390_vpklsgs:
9613 case Intrinsic::s390_vpdi:
9614 case Intrinsic::s390_vsldb:
9615 case Intrinsic::s390_vperm:
9616 computeKnownBitsBinOp(Op, Known, DemandedElts, DAG, Depth, 1);
9617 break;
9618 case Intrinsic::s390_vuplhb: // VECTOR UNPACK LOGICAL HIGH
9619 case Intrinsic::s390_vuplhh:
9620 case Intrinsic::s390_vuplhf:
9621 case Intrinsic::s390_vupllb: // VECTOR UNPACK LOGICAL LOW
9622 case Intrinsic::s390_vupllh:
9623 case Intrinsic::s390_vupllf:
9624 IsLogical = true;
9625 [[fallthrough]];
9626 case Intrinsic::s390_vuphb: // VECTOR UNPACK HIGH
9627 case Intrinsic::s390_vuphh:
9628 case Intrinsic::s390_vuphf:
9629 case Intrinsic::s390_vuplb: // VECTOR UNPACK LOW
9630 case Intrinsic::s390_vuplhw:
9631 case Intrinsic::s390_vuplf: {
9632 SDValue SrcOp = Op.getOperand(1);
9633 APInt SrcDemE = getDemandedSrcElements(Op, DemandedElts, 0);
9634 Known = DAG.computeKnownBits(SrcOp, SrcDemE, Depth + 1);
9635 if (IsLogical) {
9636 Known = Known.zext(BitWidth);
9637 } else
9638 Known = Known.sext(BitWidth);
9639 break;
9640 }
9641 default:
9642 break;
9643 }
9644 } else {
9645 switch (Opcode) {
9646 case SystemZISD::JOIN_DWORDS:
9647 case SystemZISD::SELECT_CCMASK:
9648 computeKnownBitsBinOp(Op, Known, DemandedElts, DAG, Depth, 0);
9649 break;
9650 case SystemZISD::REPLICATE: {
9651 SDValue SrcOp = Op.getOperand(0);
9652 Known = DAG.computeKnownBits(SrcOp, Depth + 1);
9653 if (Known.getBitWidth() < BitWidth && isa<ConstantSDNode>(SrcOp))
9654 Known = Known.sext(BitWidth); // VREPI sign extends the immedate.
9655 break;
9656 }
9657 default:
9658 break;
9659 }
9660 }
9661
9662 // Known has the width of the source operand(s). Adjust if needed to match
9663 // the passed bitwidth.
9664 if (Known.getBitWidth() != BitWidth)
9665 Known = Known.anyextOrTrunc(BitWidth);
9666}
9667
9668static unsigned computeNumSignBitsBinOp(SDValue Op, const APInt &DemandedElts,
9669 const SelectionDAG &DAG, unsigned Depth,
9670 unsigned OpNo) {
9671 APInt Src0DemE = getDemandedSrcElements(Op, DemandedElts, OpNo);
9672 unsigned LHS = DAG.ComputeNumSignBits(Op.getOperand(OpNo), Src0DemE, Depth + 1);
9673 if (LHS == 1) return 1; // Early out.
9674 APInt Src1DemE = getDemandedSrcElements(Op, DemandedElts, OpNo + 1);
9675 unsigned RHS = DAG.ComputeNumSignBits(Op.getOperand(OpNo + 1), Src1DemE, Depth + 1);
9676 if (RHS == 1) return 1; // Early out.
9677 unsigned Common = std::min(LHS, RHS);
9678 unsigned SrcBitWidth = Op.getOperand(OpNo).getScalarValueSizeInBits();
9679 EVT VT = Op.getValueType();
9680 unsigned VTBits = VT.getScalarSizeInBits();
9681 if (SrcBitWidth > VTBits) { // PACK
9682 unsigned SrcExtraBits = SrcBitWidth - VTBits;
9683 if (Common > SrcExtraBits)
9684 return (Common - SrcExtraBits);
9685 return 1;
9686 }
9687 assert (SrcBitWidth == VTBits && "Expected operands of same bitwidth.");
9688 return Common;
9689}
9690
9691unsigned
9693 SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG,
9694 unsigned Depth) const {
9695 if (Op.getResNo() != 0)
9696 return 1;
9697 unsigned Opcode = Op.getOpcode();
9698 if (Opcode == ISD::INTRINSIC_WO_CHAIN) {
9699 unsigned Id = Op.getConstantOperandVal(0);
9700 switch (Id) {
9701 case Intrinsic::s390_vpksh: // PACKS
9702 case Intrinsic::s390_vpksf:
9703 case Intrinsic::s390_vpksg:
9704 case Intrinsic::s390_vpkshs: // PACKS_CC
9705 case Intrinsic::s390_vpksfs:
9706 case Intrinsic::s390_vpksgs:
9707 case Intrinsic::s390_vpklsh: // PACKLS
9708 case Intrinsic::s390_vpklsf:
9709 case Intrinsic::s390_vpklsg:
9710 case Intrinsic::s390_vpklshs: // PACKLS_CC
9711 case Intrinsic::s390_vpklsfs:
9712 case Intrinsic::s390_vpklsgs:
9713 case Intrinsic::s390_vpdi:
9714 case Intrinsic::s390_vsldb:
9715 case Intrinsic::s390_vperm:
9716 return computeNumSignBitsBinOp(Op, DemandedElts, DAG, Depth, 1);
9717 case Intrinsic::s390_vuphb: // VECTOR UNPACK HIGH
9718 case Intrinsic::s390_vuphh:
9719 case Intrinsic::s390_vuphf:
9720 case Intrinsic::s390_vuplb: // VECTOR UNPACK LOW
9721 case Intrinsic::s390_vuplhw:
9722 case Intrinsic::s390_vuplf: {
9723 SDValue PackedOp = Op.getOperand(1);
9724 APInt SrcDemE = getDemandedSrcElements(Op, DemandedElts, 1);
9725 unsigned Tmp = DAG.ComputeNumSignBits(PackedOp, SrcDemE, Depth + 1);
9726 EVT VT = Op.getValueType();
9727 unsigned VTBits = VT.getScalarSizeInBits();
9728 Tmp += VTBits - PackedOp.getScalarValueSizeInBits();
9729 return Tmp;
9730 }
9731 default:
9732 break;
9733 }
9734 } else {
9735 switch (Opcode) {
9736 case SystemZISD::SELECT_CCMASK:
9737 return computeNumSignBitsBinOp(Op, DemandedElts, DAG, Depth, 0);
9738 default:
9739 break;
9740 }
9741 }
9742
9743 return 1;
9744}
9745
9747 SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG,
9748 UndefPoisonKind Kind, unsigned Depth) const {
9749 switch (Op->getOpcode()) {
9750 case SystemZISD::PCREL_WRAPPER:
9751 case SystemZISD::PCREL_OFFSET:
9752 return true;
9753 }
9754 return false;
9755}
9756
9757unsigned
9759 const TargetFrameLowering *TFI = Subtarget.getFrameLowering();
9760 unsigned StackAlign = TFI->getStackAlignment();
9761 assert(StackAlign >=1 && isPowerOf2_32(StackAlign) &&
9762 "Unexpected stack alignment");
9763 // The default stack probe size is 4096 if the function has no
9764 // stack-probe-size attribute.
9765 unsigned StackProbeSize =
9766 MF.getFunction().getFnAttributeAsParsedInteger("stack-probe-size", 4096);
9767 // Round down to the stack alignment.
9768 StackProbeSize &= ~(StackAlign - 1);
9769 return StackProbeSize ? StackProbeSize : StackAlign;
9770}
9771
9772//===----------------------------------------------------------------------===//
9773// Custom insertion
9774//===----------------------------------------------------------------------===//
9775
9776// Force base value Base into a register before MI. Return the register.
9778 const SystemZInstrInfo *TII) {
9779 MachineBasicBlock *MBB = MI.getParent();
9780 MachineFunction &MF = *MBB->getParent();
9781 MachineRegisterInfo &MRI = MF.getRegInfo();
9782
9783 if (Base.isReg()) {
9784 // Copy Base into a new virtual register to help register coalescing in
9785 // cases with multiple uses.
9786 Register Reg = MRI.createVirtualRegister(&SystemZ::ADDR64BitRegClass);
9787 BuildMI(*MBB, MI, MI.getDebugLoc(), TII->get(SystemZ::COPY), Reg)
9788 .add(Base);
9789 return Reg;
9790 }
9791
9792 Register Reg = MRI.createVirtualRegister(&SystemZ::ADDR64BitRegClass);
9793 BuildMI(*MBB, MI, MI.getDebugLoc(), TII->get(SystemZ::LA), Reg)
9794 .add(Base)
9795 .addImm(0)
9796 .addReg(0);
9797 return Reg;
9798}
9799
9800// The CC operand of MI might be missing a kill marker because there
9801// were multiple uses of CC, and ISel didn't know which to mark.
9802// Figure out whether MI should have had a kill marker.
9804 // Scan forward through BB for a use/def of CC.
9806 for (MachineBasicBlock::iterator miE = MBB->end(); miI != miE; ++miI) {
9807 const MachineInstr &MI = *miI;
9808 if (MI.readsRegister(SystemZ::CC, /*TRI=*/nullptr))
9809 return false;
9810 if (MI.definesRegister(SystemZ::CC, /*TRI=*/nullptr))
9811 break; // Should have kill-flag - update below.
9812 }
9813
9814 // If we hit the end of the block, check whether CC is live into a
9815 // successor.
9816 if (miI == MBB->end()) {
9817 for (const MachineBasicBlock *Succ : MBB->successors())
9818 if (Succ->isLiveIn(SystemZ::CC))
9819 return false;
9820 }
9821
9822 return true;
9823}
9824
9825// Return true if it is OK for this Select pseudo-opcode to be cascaded
9826// together with other Select pseudo-opcodes into a single basic-block with
9827// a conditional jump around it.
9829 switch (MI.getOpcode()) {
9830 case SystemZ::Select32:
9831 case SystemZ::Select64:
9832 case SystemZ::Select128:
9833 case SystemZ::SelectF32:
9834 case SystemZ::SelectF64:
9835 case SystemZ::SelectF128:
9836 case SystemZ::SelectVR32:
9837 case SystemZ::SelectVR64:
9838 case SystemZ::SelectVR128:
9839 return true;
9840
9841 default:
9842 return false;
9843 }
9844}
9845
9846// Helper function, which inserts PHI functions into SinkMBB:
9847// %Result(i) = phi [ %FalseValue(i), FalseMBB ], [ %TrueValue(i), TrueMBB ],
9848// where %FalseValue(i) and %TrueValue(i) are taken from Selects.
9850 MachineBasicBlock *TrueMBB,
9851 MachineBasicBlock *FalseMBB,
9852 MachineBasicBlock *SinkMBB) {
9853 MachineFunction *MF = TrueMBB->getParent();
9855
9856 MachineInstr *FirstMI = Selects.front();
9857 unsigned CCValid = FirstMI->getOperand(3).getImm();
9858 unsigned CCMask = FirstMI->getOperand(4).getImm();
9859
9860 MachineBasicBlock::iterator SinkInsertionPoint = SinkMBB->begin();
9861
9862 // As we are creating the PHIs, we have to be careful if there is more than
9863 // one. Later Selects may reference the results of earlier Selects, but later
9864 // PHIs have to reference the individual true/false inputs from earlier PHIs.
9865 // That also means that PHI construction must work forward from earlier to
9866 // later, and that the code must maintain a mapping from earlier PHI's
9867 // destination registers, and the registers that went into the PHI.
9869
9870 for (auto *MI : Selects) {
9871 Register DestReg = MI->getOperand(0).getReg();
9872 Register TrueReg = MI->getOperand(1).getReg();
9873 Register FalseReg = MI->getOperand(2).getReg();
9874
9875 // If this Select we are generating is the opposite condition from
9876 // the jump we generated, then we have to swap the operands for the
9877 // PHI that is going to be generated.
9878 if (MI->getOperand(4).getImm() == (CCValid ^ CCMask))
9879 std::swap(TrueReg, FalseReg);
9880
9881 if (auto It = RegRewriteTable.find(TrueReg); It != RegRewriteTable.end())
9882 TrueReg = It->second.first;
9883
9884 if (auto It = RegRewriteTable.find(FalseReg); It != RegRewriteTable.end())
9885 FalseReg = It->second.second;
9886
9887 DebugLoc DL = MI->getDebugLoc();
9888 BuildMI(*SinkMBB, SinkInsertionPoint, DL, TII->get(SystemZ::PHI), DestReg)
9889 .addReg(TrueReg).addMBB(TrueMBB)
9890 .addReg(FalseReg).addMBB(FalseMBB);
9891
9892 // Add this PHI to the rewrite table.
9893 RegRewriteTable[DestReg] = std::make_pair(TrueReg, FalseReg);
9894 }
9895
9896 MF->getProperties().resetNoPHIs();
9897}
9898
9900SystemZTargetLowering::emitAdjCallStack(MachineInstr &MI,
9901 MachineBasicBlock *BB) const {
9902 MachineFunction &MF = *BB->getParent();
9903 MachineFrameInfo &MFI = MF.getFrameInfo();
9904 auto *TFL = Subtarget.getFrameLowering<SystemZFrameLowering>();
9905 assert(TFL->hasReservedCallFrame(MF) &&
9906 "ADJSTACKDOWN and ADJSTACKUP should be no-ops");
9907 (void)TFL;
9908 // Get the MaxCallFrameSize value and erase MI since it serves no further
9909 // purpose as the call frame is statically reserved in the prolog. Set
9910 // AdjustsStack as MI is *not* mapped as a frame instruction.
9911 uint32_t NumBytes = MI.getOperand(0).getImm();
9912 if (NumBytes > MFI.getMaxCallFrameSize())
9913 MFI.setMaxCallFrameSize(NumBytes);
9914 MFI.setAdjustsStack(true);
9915
9916 MI.eraseFromParent();
9917 return BB;
9918}
9919
9920// Implement EmitInstrWithCustomInserter for pseudo Select* instruction MI.
9922SystemZTargetLowering::emitSelect(MachineInstr &MI,
9923 MachineBasicBlock *MBB) const {
9924 assert(isSelectPseudo(MI) && "Bad call to emitSelect()");
9925 const SystemZInstrInfo *TII = Subtarget.getInstrInfo();
9926
9927 unsigned CCValid = MI.getOperand(3).getImm();
9928 unsigned CCMask = MI.getOperand(4).getImm();
9929
9930 // If we have a sequence of Select* pseudo instructions using the
9931 // same condition code value, we want to expand all of them into
9932 // a single pair of basic blocks using the same condition.
9933 SmallVector<MachineInstr*, 8> Selects;
9934 SmallVector<MachineInstr*, 8> DbgValues;
9935 Selects.push_back(&MI);
9936 unsigned Count = 0;
9937 for (MachineInstr &NextMI : llvm::make_range(
9938 std::next(MachineBasicBlock::iterator(MI)), MBB->end())) {
9939 if (isSelectPseudo(NextMI)) {
9940 assert(NextMI.getOperand(3).getImm() == CCValid &&
9941 "Bad CCValid operands since CC was not redefined.");
9942 if (NextMI.getOperand(4).getImm() == CCMask ||
9943 NextMI.getOperand(4).getImm() == (CCValid ^ CCMask)) {
9944 Selects.push_back(&NextMI);
9945 continue;
9946 }
9947 break;
9948 }
9949 if (NextMI.definesRegister(SystemZ::CC, /*TRI=*/nullptr) ||
9950 NextMI.usesCustomInsertionHook())
9951 break;
9952 bool User = false;
9953 for (auto *SelMI : Selects)
9954 if (NextMI.readsVirtualRegister(SelMI->getOperand(0).getReg())) {
9955 User = true;
9956 break;
9957 }
9958 if (NextMI.isDebugInstr()) {
9959 if (User) {
9960 assert(NextMI.isDebugValue() && "Unhandled debug opcode.");
9961 DbgValues.push_back(&NextMI);
9962 }
9963 } else if (User || ++Count > 20)
9964 break;
9965 }
9966
9967 MachineInstr *LastMI = Selects.back();
9968 bool CCKilled = (LastMI->killsRegister(SystemZ::CC, /*TRI=*/nullptr) ||
9969 checkCCKill(*LastMI, MBB));
9970 MachineBasicBlock *StartMBB = MBB;
9971 MachineBasicBlock *JoinMBB = SystemZ::splitBlockAfter(LastMI, MBB);
9972 MachineBasicBlock *FalseMBB = SystemZ::emitBlockAfter(StartMBB);
9973
9974 // Unless CC was killed in the last Select instruction, mark it as
9975 // live-in to both FalseMBB and JoinMBB.
9976 if (!CCKilled) {
9977 FalseMBB->addLiveIn(SystemZ::CC);
9978 JoinMBB->addLiveIn(SystemZ::CC);
9979 }
9980
9981 // StartMBB:
9982 // BRC CCMask, JoinMBB
9983 // # fallthrough to FalseMBB
9984 MBB = StartMBB;
9985 BuildMI(MBB, MI.getDebugLoc(), TII->get(SystemZ::BRC))
9986 .addImm(CCValid).addImm(CCMask).addMBB(JoinMBB);
9987 MBB->addSuccessor(JoinMBB);
9988 MBB->addSuccessor(FalseMBB);
9989
9990 // FalseMBB:
9991 // # fallthrough to JoinMBB
9992 MBB = FalseMBB;
9993 MBB->addSuccessor(JoinMBB);
9994
9995 // JoinMBB:
9996 // %Result = phi [ %FalseReg, FalseMBB ], [ %TrueReg, StartMBB ]
9997 // ...
9998 MBB = JoinMBB;
9999 createPHIsForSelects(Selects, StartMBB, FalseMBB, MBB);
10000 for (auto *SelMI : Selects)
10001 SelMI->eraseFromParent();
10002
10004 for (auto *DbgMI : DbgValues)
10005 MBB->splice(InsertPos, StartMBB, DbgMI);
10006
10007 return JoinMBB;
10008}
10009
10010// Implement EmitInstrWithCustomInserter for pseudo CondStore* instruction MI.
10011// StoreOpcode is the store to use and Invert says whether the store should
10012// happen when the condition is false rather than true. If a STORE ON
10013// CONDITION is available, STOCOpcode is its opcode, otherwise it is 0.
10014MachineBasicBlock *SystemZTargetLowering::emitCondStore(MachineInstr &MI,
10016 unsigned StoreOpcode,
10017 unsigned STOCOpcode,
10018 bool Invert) const {
10019 const SystemZInstrInfo *TII = Subtarget.getInstrInfo();
10020
10021 Register SrcReg = MI.getOperand(0).getReg();
10022 MachineOperand Base = MI.getOperand(1);
10023 int64_t Disp = MI.getOperand(2).getImm();
10024 Register IndexReg = MI.getOperand(3).getReg();
10025 unsigned CCValid = MI.getOperand(4).getImm();
10026 unsigned CCMask = MI.getOperand(5).getImm();
10027 DebugLoc DL = MI.getDebugLoc();
10028
10029 StoreOpcode = TII->getOpcodeForOffset(StoreOpcode, Disp);
10030
10031 // ISel pattern matching also adds a load memory operand of the same
10032 // address, so take special care to find the storing memory operand.
10033 MachineMemOperand *MMO = nullptr;
10034 for (auto *I : MI.memoperands())
10035 if (I->isStore()) {
10036 MMO = I;
10037 break;
10038 }
10039
10040 // Use STOCOpcode if possible. We could use different store patterns in
10041 // order to avoid matching the index register, but the performance trade-offs
10042 // might be more complicated in that case.
10043 if (STOCOpcode && !IndexReg && Subtarget.hasLoadStoreOnCond()) {
10044 if (Invert)
10045 CCMask ^= CCValid;
10046
10047 BuildMI(*MBB, MI, DL, TII->get(STOCOpcode))
10048 .addReg(SrcReg)
10049 .add(Base)
10050 .addImm(Disp)
10051 .addImm(CCValid)
10052 .addImm(CCMask)
10053 .addMemOperand(MMO);
10054
10055 MI.eraseFromParent();
10056 return MBB;
10057 }
10058
10059 // Get the condition needed to branch around the store.
10060 if (!Invert)
10061 CCMask ^= CCValid;
10062
10063 MachineBasicBlock *StartMBB = MBB;
10064 MachineBasicBlock *JoinMBB = SystemZ::splitBlockBefore(MI, MBB);
10065 MachineBasicBlock *FalseMBB = SystemZ::emitBlockAfter(StartMBB);
10066
10067 // Unless CC was killed in the CondStore instruction, mark it as
10068 // live-in to both FalseMBB and JoinMBB.
10069 if (!MI.killsRegister(SystemZ::CC, /*TRI=*/nullptr) &&
10070 !checkCCKill(MI, JoinMBB)) {
10071 FalseMBB->addLiveIn(SystemZ::CC);
10072 JoinMBB->addLiveIn(SystemZ::CC);
10073 }
10074
10075 // StartMBB:
10076 // BRC CCMask, JoinMBB
10077 // # fallthrough to FalseMBB
10078 MBB = StartMBB;
10079 BuildMI(MBB, DL, TII->get(SystemZ::BRC))
10080 .addImm(CCValid).addImm(CCMask).addMBB(JoinMBB);
10081 MBB->addSuccessor(JoinMBB);
10082 MBB->addSuccessor(FalseMBB);
10083
10084 // FalseMBB:
10085 // store %SrcReg, %Disp(%Index,%Base)
10086 // # fallthrough to JoinMBB
10087 MBB = FalseMBB;
10088 BuildMI(MBB, DL, TII->get(StoreOpcode))
10089 .addReg(SrcReg)
10090 .add(Base)
10091 .addImm(Disp)
10092 .addReg(IndexReg)
10093 .addMemOperand(MMO);
10094 MBB->addSuccessor(JoinMBB);
10095
10096 MI.eraseFromParent();
10097 return JoinMBB;
10098}
10099
10100// Implement EmitInstrWithCustomInserter for pseudo [SU]Cmp128Hi instruction MI.
10102SystemZTargetLowering::emitICmp128Hi(MachineInstr &MI,
10104 bool Unsigned) const {
10105 MachineFunction &MF = *MBB->getParent();
10106 const SystemZInstrInfo *TII = Subtarget.getInstrInfo();
10107 MachineRegisterInfo &MRI = MF.getRegInfo();
10108
10109 // Synthetic instruction to compare 128-bit values.
10110 // Sets CC 1 if Op0 > Op1, sets a different CC otherwise.
10111 Register Op0 = MI.getOperand(0).getReg();
10112 Register Op1 = MI.getOperand(1).getReg();
10113
10114 MachineBasicBlock *StartMBB = MBB;
10115 MachineBasicBlock *JoinMBB = SystemZ::splitBlockAfter(MI, MBB);
10116 MachineBasicBlock *HiEqMBB = SystemZ::emitBlockAfter(StartMBB);
10117
10118 // StartMBB:
10119 //
10120 // Use VECTOR ELEMENT COMPARE [LOGICAL] to compare the high parts.
10121 // Swap the inputs to get:
10122 // CC 1 if high(Op0) > high(Op1)
10123 // CC 2 if high(Op0) < high(Op1)
10124 // CC 0 if high(Op0) == high(Op1)
10125 //
10126 // If CC != 0, we'd done, so jump over the next instruction.
10127 //
10128 // VEC[L]G Op1, Op0
10129 // JNE JoinMBB
10130 // # fallthrough to HiEqMBB
10131 MBB = StartMBB;
10132 int HiOpcode = Unsigned? SystemZ::VECLG : SystemZ::VECG;
10133 BuildMI(MBB, MI.getDebugLoc(), TII->get(HiOpcode))
10134 .addReg(Op1).addReg(Op0);
10135 BuildMI(MBB, MI.getDebugLoc(), TII->get(SystemZ::BRC))
10137 MBB->addSuccessor(JoinMBB);
10138 MBB->addSuccessor(HiEqMBB);
10139
10140 // HiEqMBB:
10141 //
10142 // Otherwise, use VECTOR COMPARE HIGH LOGICAL.
10143 // Since we already know the high parts are equal, the CC
10144 // result will only depend on the low parts:
10145 // CC 1 if low(Op0) > low(Op1)
10146 // CC 3 if low(Op0) <= low(Op1)
10147 //
10148 // VCHLGS Tmp, Op0, Op1
10149 // # fallthrough to JoinMBB
10150 MBB = HiEqMBB;
10151 Register Temp = MRI.createVirtualRegister(&SystemZ::VR128BitRegClass);
10152 BuildMI(MBB, MI.getDebugLoc(), TII->get(SystemZ::VCHLGS), Temp)
10153 .addReg(Op0).addReg(Op1);
10154 MBB->addSuccessor(JoinMBB);
10155
10156 // Mark CC as live-in to JoinMBB.
10157 JoinMBB->addLiveIn(SystemZ::CC);
10158
10159 MI.eraseFromParent();
10160 return JoinMBB;
10161}
10162
10163// Implement EmitInstrWithCustomInserter for subword pseudo ATOMIC_LOADW_* or
10164// ATOMIC_SWAPW instruction MI. BinOpcode is the instruction that performs
10165// the binary operation elided by "*", or 0 for ATOMIC_SWAPW. Invert says
10166// whether the field should be inverted after performing BinOpcode (e.g. for
10167// NAND).
10168MachineBasicBlock *SystemZTargetLowering::emitAtomicLoadBinary(
10169 MachineInstr &MI, MachineBasicBlock *MBB, unsigned BinOpcode,
10170 bool Invert) const {
10171 MachineFunction &MF = *MBB->getParent();
10172 const SystemZInstrInfo *TII = Subtarget.getInstrInfo();
10173 MachineRegisterInfo &MRI = MF.getRegInfo();
10174
10175 // Extract the operands. Base can be a register or a frame index.
10176 // Src2 can be a register or immediate.
10177 Register Dest = MI.getOperand(0).getReg();
10178 MachineOperand Base = earlyUseOperand(MI.getOperand(1));
10179 int64_t Disp = MI.getOperand(2).getImm();
10180 MachineOperand Src2 = earlyUseOperand(MI.getOperand(3));
10181 Register BitShift = MI.getOperand(4).getReg();
10182 Register NegBitShift = MI.getOperand(5).getReg();
10183 unsigned BitSize = MI.getOperand(6).getImm();
10184 DebugLoc DL = MI.getDebugLoc();
10185
10186 // Get the right opcodes for the displacement.
10187 unsigned LOpcode = TII->getOpcodeForOffset(SystemZ::L, Disp);
10188 unsigned CSOpcode = TII->getOpcodeForOffset(SystemZ::CS, Disp);
10189 assert(LOpcode && CSOpcode && "Displacement out of range");
10190
10191 // Create virtual registers for temporary results.
10192 Register OrigVal = MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10193 Register OldVal = MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10194 Register NewVal = MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10195 Register RotatedOldVal = MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10196 Register RotatedNewVal = MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10197
10198 // Insert a basic block for the main loop.
10199 MachineBasicBlock *StartMBB = MBB;
10200 MachineBasicBlock *DoneMBB = SystemZ::splitBlockBefore(MI, MBB);
10201 MachineBasicBlock *LoopMBB = SystemZ::emitBlockAfter(StartMBB);
10202
10203 // StartMBB:
10204 // ...
10205 // %OrigVal = L Disp(%Base)
10206 // # fall through to LoopMBB
10207 MBB = StartMBB;
10208 BuildMI(MBB, DL, TII->get(LOpcode), OrigVal).add(Base).addImm(Disp).addReg(0);
10209 MBB->addSuccessor(LoopMBB);
10210
10211 // LoopMBB:
10212 // %OldVal = phi [ %OrigVal, StartMBB ], [ %Dest, LoopMBB ]
10213 // %RotatedOldVal = RLL %OldVal, 0(%BitShift)
10214 // %RotatedNewVal = OP %RotatedOldVal, %Src2
10215 // %NewVal = RLL %RotatedNewVal, 0(%NegBitShift)
10216 // %Dest = CS %OldVal, %NewVal, Disp(%Base)
10217 // JNE LoopMBB
10218 // # fall through to DoneMBB
10219 MBB = LoopMBB;
10220 BuildMI(MBB, DL, TII->get(SystemZ::PHI), OldVal)
10221 .addReg(OrigVal).addMBB(StartMBB)
10222 .addReg(Dest).addMBB(LoopMBB);
10223 BuildMI(MBB, DL, TII->get(SystemZ::RLL), RotatedOldVal)
10224 .addReg(OldVal).addReg(BitShift).addImm(0);
10225 if (Invert) {
10226 // Perform the operation normally and then invert every bit of the field.
10227 Register Tmp = MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10228 BuildMI(MBB, DL, TII->get(BinOpcode), Tmp).addReg(RotatedOldVal).add(Src2);
10229 // XILF with the upper BitSize bits set.
10230 BuildMI(MBB, DL, TII->get(SystemZ::XILF), RotatedNewVal)
10231 .addReg(Tmp).addImm(-1U << (32 - BitSize));
10232 } else if (BinOpcode)
10233 // A simply binary operation.
10234 BuildMI(MBB, DL, TII->get(BinOpcode), RotatedNewVal)
10235 .addReg(RotatedOldVal)
10236 .add(Src2);
10237 else
10238 // Use RISBG to rotate Src2 into position and use it to replace the
10239 // field in RotatedOldVal.
10240 BuildMI(MBB, DL, TII->get(SystemZ::RISBG32), RotatedNewVal)
10241 .addReg(RotatedOldVal).addReg(Src2.getReg())
10242 .addImm(32).addImm(31 + BitSize).addImm(32 - BitSize);
10243 BuildMI(MBB, DL, TII->get(SystemZ::RLL), NewVal)
10244 .addReg(RotatedNewVal).addReg(NegBitShift).addImm(0);
10245 BuildMI(MBB, DL, TII->get(CSOpcode), Dest)
10246 .addReg(OldVal)
10247 .addReg(NewVal)
10248 .add(Base)
10249 .addImm(Disp);
10250 BuildMI(MBB, DL, TII->get(SystemZ::BRC))
10252 MBB->addSuccessor(LoopMBB);
10253 MBB->addSuccessor(DoneMBB);
10254
10255 MI.eraseFromParent();
10256 return DoneMBB;
10257}
10258
10259// Implement EmitInstrWithCustomInserter for subword pseudo
10260// ATOMIC_LOADW_{,U}{MIN,MAX} instruction MI. CompareOpcode is the
10261// instruction that should be used to compare the current field with the
10262// minimum or maximum value. KeepOldMask is the BRC condition-code mask
10263// for when the current field should be kept.
10264MachineBasicBlock *SystemZTargetLowering::emitAtomicLoadMinMax(
10265 MachineInstr &MI, MachineBasicBlock *MBB, unsigned CompareOpcode,
10266 unsigned KeepOldMask) const {
10267 MachineFunction &MF = *MBB->getParent();
10268 const SystemZInstrInfo *TII = Subtarget.getInstrInfo();
10269 MachineRegisterInfo &MRI = MF.getRegInfo();
10270
10271 // Extract the operands. Base can be a register or a frame index.
10272 Register Dest = MI.getOperand(0).getReg();
10273 MachineOperand Base = earlyUseOperand(MI.getOperand(1));
10274 int64_t Disp = MI.getOperand(2).getImm();
10275 Register Src2 = MI.getOperand(3).getReg();
10276 Register BitShift = MI.getOperand(4).getReg();
10277 Register NegBitShift = MI.getOperand(5).getReg();
10278 unsigned BitSize = MI.getOperand(6).getImm();
10279 DebugLoc DL = MI.getDebugLoc();
10280
10281 // Get the right opcodes for the displacement.
10282 unsigned LOpcode = TII->getOpcodeForOffset(SystemZ::L, Disp);
10283 unsigned CSOpcode = TII->getOpcodeForOffset(SystemZ::CS, Disp);
10284 assert(LOpcode && CSOpcode && "Displacement out of range");
10285
10286 // Create virtual registers for temporary results.
10287 Register OrigVal = MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10288 Register OldVal = MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10289 Register NewVal = MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10290 Register RotatedOldVal = MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10291 Register RotatedAltVal = MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10292 Register RotatedNewVal = MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10293
10294 // Insert 3 basic blocks for the loop.
10295 MachineBasicBlock *StartMBB = MBB;
10296 MachineBasicBlock *DoneMBB = SystemZ::splitBlockBefore(MI, MBB);
10297 MachineBasicBlock *LoopMBB = SystemZ::emitBlockAfter(StartMBB);
10298 MachineBasicBlock *UseAltMBB = SystemZ::emitBlockAfter(LoopMBB);
10299 MachineBasicBlock *UpdateMBB = SystemZ::emitBlockAfter(UseAltMBB);
10300
10301 // StartMBB:
10302 // ...
10303 // %OrigVal = L Disp(%Base)
10304 // # fall through to LoopMBB
10305 MBB = StartMBB;
10306 BuildMI(MBB, DL, TII->get(LOpcode), OrigVal).add(Base).addImm(Disp).addReg(0);
10307 MBB->addSuccessor(LoopMBB);
10308
10309 // LoopMBB:
10310 // %OldVal = phi [ %OrigVal, StartMBB ], [ %Dest, UpdateMBB ]
10311 // %RotatedOldVal = RLL %OldVal, 0(%BitShift)
10312 // CompareOpcode %RotatedOldVal, %Src2
10313 // BRC KeepOldMask, UpdateMBB
10314 MBB = LoopMBB;
10315 BuildMI(MBB, DL, TII->get(SystemZ::PHI), OldVal)
10316 .addReg(OrigVal).addMBB(StartMBB)
10317 .addReg(Dest).addMBB(UpdateMBB);
10318 BuildMI(MBB, DL, TII->get(SystemZ::RLL), RotatedOldVal)
10319 .addReg(OldVal).addReg(BitShift).addImm(0);
10320 BuildMI(MBB, DL, TII->get(CompareOpcode))
10321 .addReg(RotatedOldVal).addReg(Src2);
10322 BuildMI(MBB, DL, TII->get(SystemZ::BRC))
10323 .addImm(SystemZ::CCMASK_ICMP).addImm(KeepOldMask).addMBB(UpdateMBB);
10324 MBB->addSuccessor(UpdateMBB);
10325 MBB->addSuccessor(UseAltMBB);
10326
10327 // UseAltMBB:
10328 // %RotatedAltVal = RISBG %RotatedOldVal, %Src2, 32, 31 + BitSize, 0
10329 // # fall through to UpdateMBB
10330 MBB = UseAltMBB;
10331 BuildMI(MBB, DL, TII->get(SystemZ::RISBG32), RotatedAltVal)
10332 .addReg(RotatedOldVal).addReg(Src2)
10333 .addImm(32).addImm(31 + BitSize).addImm(0);
10334 MBB->addSuccessor(UpdateMBB);
10335
10336 // UpdateMBB:
10337 // %RotatedNewVal = PHI [ %RotatedOldVal, LoopMBB ],
10338 // [ %RotatedAltVal, UseAltMBB ]
10339 // %NewVal = RLL %RotatedNewVal, 0(%NegBitShift)
10340 // %Dest = CS %OldVal, %NewVal, Disp(%Base)
10341 // JNE LoopMBB
10342 // # fall through to DoneMBB
10343 MBB = UpdateMBB;
10344 BuildMI(MBB, DL, TII->get(SystemZ::PHI), RotatedNewVal)
10345 .addReg(RotatedOldVal).addMBB(LoopMBB)
10346 .addReg(RotatedAltVal).addMBB(UseAltMBB);
10347 BuildMI(MBB, DL, TII->get(SystemZ::RLL), NewVal)
10348 .addReg(RotatedNewVal).addReg(NegBitShift).addImm(0);
10349 BuildMI(MBB, DL, TII->get(CSOpcode), Dest)
10350 .addReg(OldVal)
10351 .addReg(NewVal)
10352 .add(Base)
10353 .addImm(Disp);
10354 BuildMI(MBB, DL, TII->get(SystemZ::BRC))
10356 MBB->addSuccessor(LoopMBB);
10357 MBB->addSuccessor(DoneMBB);
10358
10359 MI.eraseFromParent();
10360 return DoneMBB;
10361}
10362
10363// Implement EmitInstrWithCustomInserter for subword pseudo ATOMIC_CMP_SWAPW
10364// instruction MI.
10366SystemZTargetLowering::emitAtomicCmpSwapW(MachineInstr &MI,
10367 MachineBasicBlock *MBB) const {
10368 MachineFunction &MF = *MBB->getParent();
10369 const SystemZInstrInfo *TII = Subtarget.getInstrInfo();
10370 MachineRegisterInfo &MRI = MF.getRegInfo();
10371
10372 // Extract the operands. Base can be a register or a frame index.
10373 Register Dest = MI.getOperand(0).getReg();
10374 MachineOperand Base = earlyUseOperand(MI.getOperand(1));
10375 int64_t Disp = MI.getOperand(2).getImm();
10376 Register CmpVal = MI.getOperand(3).getReg();
10377 Register OrigSwapVal = MI.getOperand(4).getReg();
10378 Register BitShift = MI.getOperand(5).getReg();
10379 Register NegBitShift = MI.getOperand(6).getReg();
10380 int64_t BitSize = MI.getOperand(7).getImm();
10381 DebugLoc DL = MI.getDebugLoc();
10382
10383 const TargetRegisterClass *RC = &SystemZ::GR32BitRegClass;
10384
10385 // Get the right opcodes for the displacement and zero-extension.
10386 unsigned LOpcode = TII->getOpcodeForOffset(SystemZ::L, Disp);
10387 unsigned CSOpcode = TII->getOpcodeForOffset(SystemZ::CS, Disp);
10388 unsigned ZExtOpcode = BitSize == 8 ? SystemZ::LLCR : SystemZ::LLHR;
10389 assert(LOpcode && CSOpcode && "Displacement out of range");
10390
10391 // Create virtual registers for temporary results.
10392 Register OrigOldVal = MRI.createVirtualRegister(RC);
10393 Register OldVal = MRI.createVirtualRegister(RC);
10394 Register SwapVal = MRI.createVirtualRegister(RC);
10395 Register StoreVal = MRI.createVirtualRegister(RC);
10396 Register OldValRot = MRI.createVirtualRegister(RC);
10397 Register RetryOldVal = MRI.createVirtualRegister(RC);
10398 Register RetrySwapVal = MRI.createVirtualRegister(RC);
10399
10400 // Insert 2 basic blocks for the loop.
10401 MachineBasicBlock *StartMBB = MBB;
10402 MachineBasicBlock *DoneMBB = SystemZ::splitBlockBefore(MI, MBB);
10403 MachineBasicBlock *LoopMBB = SystemZ::emitBlockAfter(StartMBB);
10404 MachineBasicBlock *SetMBB = SystemZ::emitBlockAfter(LoopMBB);
10405
10406 // StartMBB:
10407 // ...
10408 // %OrigOldVal = L Disp(%Base)
10409 // # fall through to LoopMBB
10410 MBB = StartMBB;
10411 BuildMI(MBB, DL, TII->get(LOpcode), OrigOldVal)
10412 .add(Base)
10413 .addImm(Disp)
10414 .addReg(0);
10415 MBB->addSuccessor(LoopMBB);
10416
10417 // LoopMBB:
10418 // %OldVal = phi [ %OrigOldVal, EntryBB ], [ %RetryOldVal, SetMBB ]
10419 // %SwapVal = phi [ %OrigSwapVal, EntryBB ], [ %RetrySwapVal, SetMBB ]
10420 // %OldValRot = RLL %OldVal, BitSize(%BitShift)
10421 // ^^ The low BitSize bits contain the field
10422 // of interest.
10423 // %RetrySwapVal = RISBG32 %SwapVal, %OldValRot, 32, 63-BitSize, 0
10424 // ^^ Replace the upper 32-BitSize bits of the
10425 // swap value with those that we loaded and rotated.
10426 // %Dest = LL[CH] %OldValRot
10427 // CR %Dest, %CmpVal
10428 // JNE DoneMBB
10429 // # Fall through to SetMBB
10430 MBB = LoopMBB;
10431 BuildMI(MBB, DL, TII->get(SystemZ::PHI), OldVal)
10432 .addReg(OrigOldVal).addMBB(StartMBB)
10433 .addReg(RetryOldVal).addMBB(SetMBB);
10434 BuildMI(MBB, DL, TII->get(SystemZ::PHI), SwapVal)
10435 .addReg(OrigSwapVal).addMBB(StartMBB)
10436 .addReg(RetrySwapVal).addMBB(SetMBB);
10437 BuildMI(MBB, DL, TII->get(SystemZ::RLL), OldValRot)
10438 .addReg(OldVal).addReg(BitShift).addImm(BitSize);
10439 BuildMI(MBB, DL, TII->get(SystemZ::RISBG32), RetrySwapVal)
10440 .addReg(SwapVal).addReg(OldValRot).addImm(32).addImm(63 - BitSize).addImm(0);
10441 BuildMI(MBB, DL, TII->get(ZExtOpcode), Dest)
10442 .addReg(OldValRot);
10443 BuildMI(MBB, DL, TII->get(SystemZ::CR))
10444 .addReg(Dest).addReg(CmpVal);
10445 BuildMI(MBB, DL, TII->get(SystemZ::BRC))
10448 MBB->addSuccessor(DoneMBB);
10449 MBB->addSuccessor(SetMBB);
10450
10451 // SetMBB:
10452 // %StoreVal = RLL %RetrySwapVal, -BitSize(%NegBitShift)
10453 // ^^ Rotate the new field to its proper position.
10454 // %RetryOldVal = CS %OldVal, %StoreVal, Disp(%Base)
10455 // JNE LoopMBB
10456 // # fall through to ExitMBB
10457 MBB = SetMBB;
10458 BuildMI(MBB, DL, TII->get(SystemZ::RLL), StoreVal)
10459 .addReg(RetrySwapVal).addReg(NegBitShift).addImm(-BitSize);
10460 BuildMI(MBB, DL, TII->get(CSOpcode), RetryOldVal)
10461 .addReg(OldVal)
10462 .addReg(StoreVal)
10463 .add(Base)
10464 .addImm(Disp);
10465 BuildMI(MBB, DL, TII->get(SystemZ::BRC))
10467 MBB->addSuccessor(LoopMBB);
10468 MBB->addSuccessor(DoneMBB);
10469
10470 // If the CC def wasn't dead in the ATOMIC_CMP_SWAPW, mark CC as live-in
10471 // to the block after the loop. At this point, CC may have been defined
10472 // either by the CR in LoopMBB or by the CS in SetMBB.
10473 if (!MI.registerDefIsDead(SystemZ::CC, /*TRI=*/nullptr))
10474 DoneMBB->addLiveIn(SystemZ::CC);
10475
10476 MI.eraseFromParent();
10477 return DoneMBB;
10478}
10479
10480// Emit a move from two GR64s to a GR128.
10482SystemZTargetLowering::emitPair128(MachineInstr &MI,
10483 MachineBasicBlock *MBB) const {
10484 const SystemZInstrInfo *TII = Subtarget.getInstrInfo();
10485 const DebugLoc &DL = MI.getDebugLoc();
10486
10487 Register Dest = MI.getOperand(0).getReg();
10488 BuildMI(*MBB, MI, DL, TII->get(TargetOpcode::REG_SEQUENCE), Dest)
10489 .add(MI.getOperand(1))
10490 .addImm(SystemZ::subreg_h64)
10491 .add(MI.getOperand(2))
10492 .addImm(SystemZ::subreg_l64);
10493 MI.eraseFromParent();
10494 return MBB;
10495}
10496
10497// Emit an extension from a GR64 to a GR128. ClearEven is true
10498// if the high register of the GR128 value must be cleared or false if
10499// it's "don't care".
10500MachineBasicBlock *SystemZTargetLowering::emitExt128(MachineInstr &MI,
10502 bool ClearEven) const {
10503 MachineFunction &MF = *MBB->getParent();
10504 const SystemZInstrInfo *TII = Subtarget.getInstrInfo();
10505 MachineRegisterInfo &MRI = MF.getRegInfo();
10506 DebugLoc DL = MI.getDebugLoc();
10507
10508 Register Dest = MI.getOperand(0).getReg();
10509 Register Src = MI.getOperand(1).getReg();
10510 Register In128 = MRI.createVirtualRegister(&SystemZ::GR128BitRegClass);
10511
10512 BuildMI(*MBB, MI, DL, TII->get(TargetOpcode::IMPLICIT_DEF), In128);
10513 if (ClearEven) {
10514 Register NewIn128 = MRI.createVirtualRegister(&SystemZ::GR128BitRegClass);
10515 Register Zero64 = MRI.createVirtualRegister(&SystemZ::GR64BitRegClass);
10516
10517 BuildMI(*MBB, MI, DL, TII->get(SystemZ::LLILL), Zero64)
10518 .addImm(0);
10519 BuildMI(*MBB, MI, DL, TII->get(TargetOpcode::INSERT_SUBREG), NewIn128)
10520 .addReg(In128).addReg(Zero64).addImm(SystemZ::subreg_h64);
10521 In128 = NewIn128;
10522 }
10523 BuildMI(*MBB, MI, DL, TII->get(TargetOpcode::INSERT_SUBREG), Dest)
10524 .addReg(In128).addReg(Src).addImm(SystemZ::subreg_l64);
10525
10526 MI.eraseFromParent();
10527 return MBB;
10528}
10529
10531SystemZTargetLowering::emitMemMemWrapper(MachineInstr &MI,
10533 unsigned Opcode, bool IsMemset) const {
10534 MachineFunction &MF = *MBB->getParent();
10535 const SystemZInstrInfo *TII = Subtarget.getInstrInfo();
10536 MachineRegisterInfo &MRI = MF.getRegInfo();
10537 DebugLoc DL = MI.getDebugLoc();
10538
10539 MachineOperand DestBase = earlyUseOperand(MI.getOperand(0));
10540 uint64_t DestDisp = MI.getOperand(1).getImm();
10541 MachineOperand SrcBase = MachineOperand::CreateReg(0U, false);
10542 uint64_t SrcDisp;
10543
10544 // Fold the displacement Disp if it is out of range.
10545 auto foldDisplIfNeeded = [&](MachineOperand &Base, uint64_t &Disp) -> void {
10546 if (!isUInt<12>(Disp)) {
10547 Register Reg = MRI.createVirtualRegister(&SystemZ::ADDR64BitRegClass);
10548 unsigned Opcode = TII->getOpcodeForOffset(SystemZ::LA, Disp);
10549 BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), TII->get(Opcode), Reg)
10550 .add(Base).addImm(Disp).addReg(0);
10552 Disp = 0;
10553 }
10554 };
10555
10556 if (!IsMemset) {
10557 SrcBase = earlyUseOperand(MI.getOperand(2));
10558 SrcDisp = MI.getOperand(3).getImm();
10559 } else {
10560 SrcBase = DestBase;
10561 SrcDisp = DestDisp++;
10562 foldDisplIfNeeded(DestBase, DestDisp);
10563 }
10564
10565 MachineOperand &LengthMO = MI.getOperand(IsMemset ? 2 : 4);
10566 bool IsImmForm = LengthMO.isImm();
10567 bool IsRegForm = !IsImmForm;
10568
10569 // Build and insert one Opcode of Length, with special treatment for memset.
10570 auto insertMemMemOp = [&](MachineBasicBlock *InsMBB,
10572 MachineOperand DBase, uint64_t DDisp,
10573 MachineOperand SBase, uint64_t SDisp,
10574 unsigned Length) -> void {
10575 assert(Length > 0 && Length <= 256 && "Building memory op with bad length.");
10576 if (IsMemset) {
10577 MachineOperand ByteMO = earlyUseOperand(MI.getOperand(3));
10578 if (ByteMO.isImm())
10579 BuildMI(*InsMBB, InsPos, DL, TII->get(SystemZ::MVI))
10580 .add(SBase).addImm(SDisp).add(ByteMO);
10581 else
10582 BuildMI(*InsMBB, InsPos, DL, TII->get(SystemZ::STC))
10583 .add(ByteMO).add(SBase).addImm(SDisp).addReg(0);
10584 if (--Length == 0)
10585 return;
10586 }
10587 BuildMI(*MBB, InsPos, DL, TII->get(Opcode))
10588 .add(DBase).addImm(DDisp).addImm(Length)
10589 .add(SBase).addImm(SDisp)
10590 .setMemRefs(MI.memoperands());
10591 };
10592
10593 bool NeedsLoop = false;
10594 uint64_t ImmLength = 0;
10595 Register LenAdjReg = SystemZ::NoRegister;
10596 if (IsImmForm) {
10597 ImmLength = LengthMO.getImm();
10598 ImmLength += IsMemset ? 2 : 1; // Add back the subtracted adjustment.
10599 if (ImmLength == 0) {
10600 MI.eraseFromParent();
10601 return MBB;
10602 }
10603 if (Opcode == SystemZ::CLC) {
10604 if (ImmLength > 3 * 256)
10605 // A two-CLC sequence is a clear win over a loop, not least because
10606 // it needs only one branch. A three-CLC sequence needs the same
10607 // number of branches as a loop (i.e. 2), but is shorter. That
10608 // brings us to lengths greater than 768 bytes. It seems relatively
10609 // likely that a difference will be found within the first 768 bytes,
10610 // so we just optimize for the smallest number of branch
10611 // instructions, in order to avoid polluting the prediction buffer
10612 // too much.
10613 NeedsLoop = true;
10614 } else if (ImmLength > 6 * 256)
10615 // The heuristic we use is to prefer loops for anything that would
10616 // require 7 or more MVCs. With these kinds of sizes there isn't much
10617 // to choose between straight-line code and looping code, since the
10618 // time will be dominated by the MVCs themselves.
10619 NeedsLoop = true;
10620 } else {
10621 NeedsLoop = true;
10622 LenAdjReg = LengthMO.getReg();
10623 }
10624
10625 // When generating more than one CLC, all but the last will need to
10626 // branch to the end when a difference is found.
10627 MachineBasicBlock *EndMBB =
10628 (Opcode == SystemZ::CLC && (ImmLength > 256 || NeedsLoop)
10630 : nullptr);
10631
10632 if (NeedsLoop) {
10633 Register StartCountReg =
10634 MRI.createVirtualRegister(&SystemZ::GR64BitRegClass);
10635 if (IsImmForm) {
10636 TII->loadImmediate(*MBB, MI, StartCountReg, ImmLength / 256);
10637 ImmLength &= 255;
10638 } else {
10639 BuildMI(*MBB, MI, DL, TII->get(SystemZ::SRLG), StartCountReg)
10640 .addReg(LenAdjReg)
10641 .addReg(0)
10642 .addImm(8);
10643 }
10644
10645 bool HaveSingleBase = DestBase.isIdenticalTo(SrcBase);
10646 auto loadZeroAddress = [&]() -> MachineOperand {
10647 Register Reg = MRI.createVirtualRegister(&SystemZ::ADDR64BitRegClass);
10648 BuildMI(*MBB, MI, DL, TII->get(SystemZ::LGHI), Reg).addImm(0);
10649 return MachineOperand::CreateReg(Reg, false);
10650 };
10651 if (DestBase.isReg() && DestBase.getReg() == SystemZ::NoRegister)
10652 DestBase = loadZeroAddress();
10653 if (SrcBase.isReg() && SrcBase.getReg() == SystemZ::NoRegister)
10654 SrcBase = HaveSingleBase ? DestBase : loadZeroAddress();
10655
10656 MachineBasicBlock *StartMBB = nullptr;
10657 MachineBasicBlock *LoopMBB = nullptr;
10658 MachineBasicBlock *NextMBB = nullptr;
10659 MachineBasicBlock *DoneMBB = nullptr;
10660 MachineBasicBlock *AllDoneMBB = nullptr;
10661
10662 Register StartSrcReg = forceReg(MI, SrcBase, TII);
10663 Register StartDestReg =
10664 (HaveSingleBase ? StartSrcReg : forceReg(MI, DestBase, TII));
10665
10666 const TargetRegisterClass *RC = &SystemZ::ADDR64BitRegClass;
10667 Register ThisSrcReg = MRI.createVirtualRegister(RC);
10668 Register ThisDestReg =
10669 (HaveSingleBase ? ThisSrcReg : MRI.createVirtualRegister(RC));
10670 Register NextSrcReg = MRI.createVirtualRegister(RC);
10671 Register NextDestReg =
10672 (HaveSingleBase ? NextSrcReg : MRI.createVirtualRegister(RC));
10673 RC = &SystemZ::GR64BitRegClass;
10674 Register ThisCountReg = MRI.createVirtualRegister(RC);
10675 Register NextCountReg = MRI.createVirtualRegister(RC);
10676
10677 if (IsRegForm) {
10678 AllDoneMBB = SystemZ::splitBlockBefore(MI, MBB);
10679 StartMBB = SystemZ::emitBlockAfter(MBB);
10680 LoopMBB = SystemZ::emitBlockAfter(StartMBB);
10681 NextMBB = (EndMBB ? SystemZ::emitBlockAfter(LoopMBB) : LoopMBB);
10682 DoneMBB = SystemZ::emitBlockAfter(NextMBB);
10683
10684 // MBB:
10685 // # Jump to AllDoneMBB if LenAdjReg means 0, or fall thru to StartMBB.
10686 BuildMI(MBB, DL, TII->get(SystemZ::CGHI))
10687 .addReg(LenAdjReg).addImm(IsMemset ? -2 : -1);
10688 BuildMI(MBB, DL, TII->get(SystemZ::BRC))
10690 .addMBB(AllDoneMBB);
10691 MBB->addSuccessor(AllDoneMBB);
10692 if (!IsMemset)
10693 MBB->addSuccessor(StartMBB);
10694 else {
10695 // MemsetOneCheckMBB:
10696 // # Jump to MemsetOneMBB for a memset of length 1, or
10697 // # fall thru to StartMBB.
10698 MachineBasicBlock *MemsetOneCheckMBB = SystemZ::emitBlockAfter(MBB);
10699 MachineBasicBlock *MemsetOneMBB = SystemZ::emitBlockAfter(&*MF.rbegin());
10700 MBB->addSuccessor(MemsetOneCheckMBB);
10701 MBB = MemsetOneCheckMBB;
10702 BuildMI(MBB, DL, TII->get(SystemZ::CGHI))
10703 .addReg(LenAdjReg).addImm(-1);
10704 BuildMI(MBB, DL, TII->get(SystemZ::BRC))
10706 .addMBB(MemsetOneMBB);
10707 MBB->addSuccessor(MemsetOneMBB, {10, 100});
10708 MBB->addSuccessor(StartMBB, {90, 100});
10709
10710 // MemsetOneMBB:
10711 // # Jump back to AllDoneMBB after a single MVI or STC.
10712 MBB = MemsetOneMBB;
10713 insertMemMemOp(MBB, MBB->end(),
10714 MachineOperand::CreateReg(StartDestReg, false), DestDisp,
10715 MachineOperand::CreateReg(StartSrcReg, false), SrcDisp,
10716 1);
10717 BuildMI(MBB, DL, TII->get(SystemZ::J)).addMBB(AllDoneMBB);
10718 MBB->addSuccessor(AllDoneMBB);
10719 }
10720
10721 // StartMBB:
10722 // # Jump to DoneMBB if %StartCountReg is zero, or fall through to LoopMBB.
10723 MBB = StartMBB;
10724 BuildMI(MBB, DL, TII->get(SystemZ::CGHI))
10725 .addReg(StartCountReg).addImm(0);
10726 BuildMI(MBB, DL, TII->get(SystemZ::BRC))
10728 .addMBB(DoneMBB);
10729 MBB->addSuccessor(DoneMBB);
10730 MBB->addSuccessor(LoopMBB);
10731 }
10732 else {
10733 StartMBB = MBB;
10734 DoneMBB = SystemZ::splitBlockBefore(MI, MBB);
10735 LoopMBB = SystemZ::emitBlockAfter(StartMBB);
10736 NextMBB = (EndMBB ? SystemZ::emitBlockAfter(LoopMBB) : LoopMBB);
10737
10738 // StartMBB:
10739 // # fall through to LoopMBB
10740 MBB->addSuccessor(LoopMBB);
10741
10742 DestBase = MachineOperand::CreateReg(NextDestReg, false);
10743 SrcBase = MachineOperand::CreateReg(NextSrcReg, false);
10744 if (EndMBB && !ImmLength)
10745 // If the loop handled the whole CLC range, DoneMBB will be empty with
10746 // CC live-through into EndMBB, so add it as live-in.
10747 DoneMBB->addLiveIn(SystemZ::CC);
10748 }
10749
10750 // LoopMBB:
10751 // %ThisDestReg = phi [ %StartDestReg, StartMBB ],
10752 // [ %NextDestReg, NextMBB ]
10753 // %ThisSrcReg = phi [ %StartSrcReg, StartMBB ],
10754 // [ %NextSrcReg, NextMBB ]
10755 // %ThisCountReg = phi [ %StartCountReg, StartMBB ],
10756 // [ %NextCountReg, NextMBB ]
10757 // ( PFD 2, 768+DestDisp(%ThisDestReg) )
10758 // Opcode DestDisp(256,%ThisDestReg), SrcDisp(%ThisSrcReg)
10759 // ( JLH EndMBB )
10760 //
10761 // The prefetch is used only for MVC. The JLH is used only for CLC.
10762 MBB = LoopMBB;
10763 BuildMI(MBB, DL, TII->get(SystemZ::PHI), ThisDestReg)
10764 .addReg(StartDestReg).addMBB(StartMBB)
10765 .addReg(NextDestReg).addMBB(NextMBB);
10766 if (!HaveSingleBase)
10767 BuildMI(MBB, DL, TII->get(SystemZ::PHI), ThisSrcReg)
10768 .addReg(StartSrcReg).addMBB(StartMBB)
10769 .addReg(NextSrcReg).addMBB(NextMBB);
10770 BuildMI(MBB, DL, TII->get(SystemZ::PHI), ThisCountReg)
10771 .addReg(StartCountReg).addMBB(StartMBB)
10772 .addReg(NextCountReg).addMBB(NextMBB);
10773 if (Opcode == SystemZ::MVC)
10774 BuildMI(MBB, DL, TII->get(SystemZ::PFD))
10776 .addReg(ThisDestReg).addImm(DestDisp - IsMemset + 768).addReg(0);
10777 insertMemMemOp(MBB, MBB->end(),
10778 MachineOperand::CreateReg(ThisDestReg, false), DestDisp,
10779 MachineOperand::CreateReg(ThisSrcReg, false), SrcDisp, 256);
10780 if (EndMBB) {
10781 BuildMI(MBB, DL, TII->get(SystemZ::BRC))
10783 .addMBB(EndMBB);
10784 MBB->addSuccessor(EndMBB);
10785 MBB->addSuccessor(NextMBB);
10786 }
10787
10788 // NextMBB:
10789 // %NextDestReg = LA 256(%ThisDestReg)
10790 // %NextSrcReg = LA 256(%ThisSrcReg)
10791 // %NextCountReg = AGHI %ThisCountReg, -1
10792 // CGHI %NextCountReg, 0
10793 // JLH LoopMBB
10794 // # fall through to DoneMBB
10795 //
10796 // The AGHI, CGHI and JLH should be converted to BRCTG by later passes.
10797 MBB = NextMBB;
10798 BuildMI(MBB, DL, TII->get(SystemZ::LA), NextDestReg)
10799 .addReg(ThisDestReg).addImm(256).addReg(0);
10800 if (!HaveSingleBase)
10801 BuildMI(MBB, DL, TII->get(SystemZ::LA), NextSrcReg)
10802 .addReg(ThisSrcReg).addImm(256).addReg(0);
10803 BuildMI(MBB, DL, TII->get(SystemZ::AGHI), NextCountReg)
10804 .addReg(ThisCountReg).addImm(-1);
10805 BuildMI(MBB, DL, TII->get(SystemZ::CGHI))
10806 .addReg(NextCountReg).addImm(0);
10807 BuildMI(MBB, DL, TII->get(SystemZ::BRC))
10809 .addMBB(LoopMBB);
10810 MBB->addSuccessor(LoopMBB);
10811 MBB->addSuccessor(DoneMBB);
10812
10813 MBB = DoneMBB;
10814 if (IsRegForm) {
10815 // DoneMBB:
10816 // # Make PHIs for RemDestReg/RemSrcReg as the loop may or may not run.
10817 // # Use EXecute Relative Long for the remainder of the bytes. The target
10818 // instruction of the EXRL will have a length field of 1 since 0 is an
10819 // illegal value. The number of bytes processed becomes (%LenAdjReg &
10820 // 0xff) + 1.
10821 // # Fall through to AllDoneMBB.
10822 Register RemSrcReg = MRI.createVirtualRegister(&SystemZ::ADDR64BitRegClass);
10823 Register RemDestReg = HaveSingleBase ? RemSrcReg
10824 : MRI.createVirtualRegister(&SystemZ::ADDR64BitRegClass);
10825 BuildMI(MBB, DL, TII->get(SystemZ::PHI), RemDestReg)
10826 .addReg(StartDestReg).addMBB(StartMBB)
10827 .addReg(NextDestReg).addMBB(NextMBB);
10828 if (!HaveSingleBase)
10829 BuildMI(MBB, DL, TII->get(SystemZ::PHI), RemSrcReg)
10830 .addReg(StartSrcReg).addMBB(StartMBB)
10831 .addReg(NextSrcReg).addMBB(NextMBB);
10832 if (IsMemset)
10833 insertMemMemOp(MBB, MBB->end(),
10834 MachineOperand::CreateReg(RemDestReg, false), DestDisp,
10835 MachineOperand::CreateReg(RemSrcReg, false), SrcDisp, 1);
10836 MachineInstrBuilder EXRL_MIB =
10837 BuildMI(MBB, DL, TII->get(SystemZ::EXRL_Pseudo))
10838 .addImm(Opcode)
10839 .addReg(LenAdjReg)
10840 .addReg(RemDestReg).addImm(DestDisp)
10841 .addReg(RemSrcReg).addImm(SrcDisp);
10842 MBB->addSuccessor(AllDoneMBB);
10843 MBB = AllDoneMBB;
10844 if (Opcode != SystemZ::MVC) {
10845 EXRL_MIB.addReg(SystemZ::CC, RegState::ImplicitDefine);
10846 if (EndMBB)
10847 MBB->addLiveIn(SystemZ::CC);
10848 }
10849 }
10850 MF.getProperties().resetNoPHIs();
10851 }
10852
10853 // Handle any remaining bytes with straight-line code.
10854 while (ImmLength > 0) {
10855 uint64_t ThisLength = std::min(ImmLength, uint64_t(256));
10856 // The previous iteration might have created out-of-range displacements.
10857 // Apply them using LA/LAY if so.
10858 foldDisplIfNeeded(DestBase, DestDisp);
10859 foldDisplIfNeeded(SrcBase, SrcDisp);
10860 insertMemMemOp(MBB, MI, DestBase, DestDisp, SrcBase, SrcDisp, ThisLength);
10861 DestDisp += ThisLength;
10862 SrcDisp += ThisLength;
10863 ImmLength -= ThisLength;
10864 // If there's another CLC to go, branch to the end if a difference
10865 // was found.
10866 if (EndMBB && ImmLength > 0) {
10867 MachineBasicBlock *NextMBB = SystemZ::splitBlockBefore(MI, MBB);
10868 BuildMI(MBB, DL, TII->get(SystemZ::BRC))
10870 .addMBB(EndMBB);
10871 MBB->addSuccessor(EndMBB);
10872 MBB->addSuccessor(NextMBB);
10873 MBB = NextMBB;
10874 }
10875 }
10876 if (EndMBB) {
10877 MBB->addSuccessor(EndMBB);
10878 MBB = EndMBB;
10879 MBB->addLiveIn(SystemZ::CC);
10880 }
10881
10882 MI.eraseFromParent();
10883 return MBB;
10884}
10885
10887SystemZTargetLowering::emitMemmoveImm(MachineInstr &MI,
10888 MachineBasicBlock *MBB) const {
10889 const SystemZInstrInfo *TII = Subtarget.getInstrInfo();
10890
10891 DebugLoc DL = MI.getDebugLoc();
10892 MachineOperand DstAddr = earlyUseOperand(MI.getOperand(0));
10893 MachineOperand SrcAddr = earlyUseOperand(MI.getOperand(1));
10894 uint64_t Len = MI.getOperand(2).getImm();
10895 assert(Len > 0 && Len <= 256 && "Memmove of of unsupported constant length.");
10896
10897 // Use MVC or MVCRL after comparing the addresses.
10898 MachineBasicBlock *DoneMBB = SystemZ::splitBlockAfter(MI, MBB);
10899 MachineBasicBlock *MvcMBB = SystemZ::emitBlockAfter(MBB);
10900 MachineBasicBlock *MvcrlMBB = SystemZ::emitBlockAfter(MvcMBB);
10901 MBB->addSuccessor(MvcMBB);
10902 MBB->addSuccessor(MvcrlMBB);
10903 MvcMBB->addSuccessor(DoneMBB);
10904 MvcrlMBB->addSuccessor(DoneMBB);
10905
10906 BuildMI(MBB, DL, TII->get(SystemZ::CLGR)).add(SrcAddr).add(DstAddr);
10907 BuildMI(MBB, DL, TII->get(SystemZ::BRC))
10909 .addMBB(MvcrlMBB);
10910
10911 BuildMI(MvcMBB, DL, TII->get(SystemZ::MVC))
10912 .add(DstAddr).addImm(0)
10913 .addImm(Len)
10914 .add(SrcAddr).addImm(0)
10915 .setMemRefs(MI.memoperands());
10916 BuildMI(MvcMBB, DL, TII->get(SystemZ::J)).addMBB(DoneMBB);
10917
10918 BuildMI(MvcrlMBB, DL, TII->get(SystemZ::LHI), SystemZ::R0L).addImm(Len - 1);
10919 BuildMI(MvcrlMBB, DL, TII->get(SystemZ::MVCRL))
10920 .add(DstAddr).addImm(0)
10921 .add(SrcAddr).addImm(0)
10922 .setMemRefs(MI.memoperands());
10923
10924 MI.eraseFromParent();
10925 return DoneMBB;
10926}
10927
10928// Decompose string pseudo-instruction MI into a loop that continually performs
10929// Opcode until CC != 3.
10930MachineBasicBlock *SystemZTargetLowering::emitStringWrapper(
10931 MachineInstr &MI, MachineBasicBlock *MBB, unsigned Opcode) const {
10932 MachineFunction &MF = *MBB->getParent();
10933 const SystemZInstrInfo *TII = Subtarget.getInstrInfo();
10934 MachineRegisterInfo &MRI = MF.getRegInfo();
10935 DebugLoc DL = MI.getDebugLoc();
10936
10937 uint64_t End1Reg = MI.getOperand(0).getReg();
10938 uint64_t Start1Reg = MI.getOperand(1).getReg();
10939 uint64_t Start2Reg = MI.getOperand(2).getReg();
10940 uint64_t CharReg = MI.getOperand(3).getReg();
10941
10942 const TargetRegisterClass *RC = &SystemZ::GR64BitRegClass;
10943 uint64_t This1Reg = MRI.createVirtualRegister(RC);
10944 uint64_t This2Reg = MRI.createVirtualRegister(RC);
10945 uint64_t End2Reg = MRI.createVirtualRegister(RC);
10946
10947 MachineBasicBlock *StartMBB = MBB;
10948 MachineBasicBlock *DoneMBB = SystemZ::splitBlockBefore(MI, MBB);
10949 MachineBasicBlock *LoopMBB = SystemZ::emitBlockAfter(StartMBB);
10950
10951 // StartMBB:
10952 // # fall through to LoopMBB
10953 MBB->addSuccessor(LoopMBB);
10954
10955 // LoopMBB:
10956 // %This1Reg = phi [ %Start1Reg, StartMBB ], [ %End1Reg, LoopMBB ]
10957 // %This2Reg = phi [ %Start2Reg, StartMBB ], [ %End2Reg, LoopMBB ]
10958 // R0L = %CharReg
10959 // %End1Reg, %End2Reg = CLST %This1Reg, %This2Reg -- uses R0L
10960 // JO LoopMBB
10961 // # fall through to DoneMBB
10962 //
10963 // The load of R0L can be hoisted by post-RA LICM.
10964 MBB = LoopMBB;
10965
10966 BuildMI(MBB, DL, TII->get(SystemZ::PHI), This1Reg)
10967 .addReg(Start1Reg).addMBB(StartMBB)
10968 .addReg(End1Reg).addMBB(LoopMBB);
10969 BuildMI(MBB, DL, TII->get(SystemZ::PHI), This2Reg)
10970 .addReg(Start2Reg).addMBB(StartMBB)
10971 .addReg(End2Reg).addMBB(LoopMBB);
10972 BuildMI(MBB, DL, TII->get(TargetOpcode::COPY), SystemZ::R0L).addReg(CharReg);
10973 BuildMI(MBB, DL, TII->get(Opcode))
10974 .addReg(End1Reg, RegState::Define).addReg(End2Reg, RegState::Define)
10975 .addReg(This1Reg).addReg(This2Reg);
10976 BuildMI(MBB, DL, TII->get(SystemZ::BRC))
10978 MBB->addSuccessor(LoopMBB);
10979 MBB->addSuccessor(DoneMBB);
10980
10981 DoneMBB->addLiveIn(SystemZ::CC);
10982
10983 MI.eraseFromParent();
10984 return DoneMBB;
10985}
10986
10987// Update TBEGIN instruction with final opcode and register clobbers.
10988MachineBasicBlock *SystemZTargetLowering::emitTransactionBegin(
10989 MachineInstr &MI, MachineBasicBlock *MBB, unsigned Opcode,
10990 bool NoFloat) const {
10991 MachineFunction &MF = *MBB->getParent();
10992 const TargetFrameLowering *TFI = Subtarget.getFrameLowering();
10993 const SystemZInstrInfo *TII = Subtarget.getInstrInfo();
10994
10995 // Update opcode.
10996 MI.setDesc(TII->get(Opcode));
10997
10998 // We cannot handle a TBEGIN that clobbers the stack or frame pointer.
10999 // Make sure to add the corresponding GRSM bits if they are missing.
11000 uint64_t Control = MI.getOperand(2).getImm();
11001 static const unsigned GPRControlBit[16] = {
11002 0x8000, 0x8000, 0x4000, 0x4000, 0x2000, 0x2000, 0x1000, 0x1000,
11003 0x0800, 0x0800, 0x0400, 0x0400, 0x0200, 0x0200, 0x0100, 0x0100
11004 };
11005 Control |= GPRControlBit[15];
11006 if (TFI->hasFP(MF))
11007 Control |= GPRControlBit[11];
11008 MI.getOperand(2).setImm(Control);
11009
11010 // Add GPR clobbers.
11011 for (int I = 0; I < 16; I++) {
11012 if ((Control & GPRControlBit[I]) == 0) {
11013 unsigned Reg = SystemZMC::GR64Regs[I];
11014 MI.addOperand(MachineOperand::CreateReg(Reg, true, true));
11015 }
11016 }
11017
11018 // Add FPR/VR clobbers.
11019 if (!NoFloat && (Control & 4) != 0) {
11020 if (Subtarget.hasVector()) {
11021 for (unsigned Reg : SystemZMC::VR128Regs) {
11022 MI.addOperand(MachineOperand::CreateReg(Reg, true, true));
11023 }
11024 } else {
11025 for (unsigned Reg : SystemZMC::FP64Regs) {
11026 MI.addOperand(MachineOperand::CreateReg(Reg, true, true));
11027 }
11028 }
11029 }
11030
11031 return MBB;
11032}
11033
11034MachineBasicBlock *SystemZTargetLowering::emitLoadAndTestCmp0(
11035 MachineInstr &MI, MachineBasicBlock *MBB, unsigned Opcode) const {
11036 MachineFunction &MF = *MBB->getParent();
11037 MachineRegisterInfo *MRI = &MF.getRegInfo();
11038 const SystemZInstrInfo *TII = Subtarget.getInstrInfo();
11039 DebugLoc DL = MI.getDebugLoc();
11040
11041 Register SrcReg = MI.getOperand(0).getReg();
11042
11043 // Create new virtual register of the same class as source.
11044 const TargetRegisterClass *RC = MRI->getRegClass(SrcReg);
11045 Register DstReg = MRI->createVirtualRegister(RC);
11046
11047 // Replace pseudo with a normal load-and-test that models the def as
11048 // well.
11049 BuildMI(*MBB, MI, DL, TII->get(Opcode), DstReg)
11050 .addReg(SrcReg)
11051 .setMIFlags(MI.getFlags());
11052 MI.eraseFromParent();
11053
11054 return MBB;
11055}
11056
11057MachineBasicBlock *SystemZTargetLowering::emitProbedAlloca(
11059 MachineFunction &MF = *MBB->getParent();
11060 MachineRegisterInfo *MRI = &MF.getRegInfo();
11061 const SystemZInstrInfo *TII = Subtarget.getInstrInfo();
11062 DebugLoc DL = MI.getDebugLoc();
11063 const unsigned ProbeSize = getStackProbeSize(MF);
11064 Register DstReg = MI.getOperand(0).getReg();
11065 Register SizeReg = MI.getOperand(2).getReg();
11066
11067 MachineBasicBlock *StartMBB = MBB;
11068 MachineBasicBlock *DoneMBB = SystemZ::splitBlockAfter(MI, MBB);
11069 MachineBasicBlock *LoopTestMBB = SystemZ::emitBlockAfter(StartMBB);
11070 MachineBasicBlock *LoopBodyMBB = SystemZ::emitBlockAfter(LoopTestMBB);
11071 MachineBasicBlock *TailTestMBB = SystemZ::emitBlockAfter(LoopBodyMBB);
11072 MachineBasicBlock *TailMBB = SystemZ::emitBlockAfter(TailTestMBB);
11073
11074 MachineMemOperand *VolLdMMO = MF.getMachineMemOperand(MachinePointerInfo(),
11076
11077 Register PHIReg = MRI->createVirtualRegister(&SystemZ::ADDR64BitRegClass);
11078 Register IncReg = MRI->createVirtualRegister(&SystemZ::ADDR64BitRegClass);
11079
11080 // LoopTestMBB
11081 // BRC TailTestMBB
11082 // # fallthrough to LoopBodyMBB
11083 StartMBB->addSuccessor(LoopTestMBB);
11084 MBB = LoopTestMBB;
11085 BuildMI(MBB, DL, TII->get(SystemZ::PHI), PHIReg)
11086 .addReg(SizeReg)
11087 .addMBB(StartMBB)
11088 .addReg(IncReg)
11089 .addMBB(LoopBodyMBB);
11090 BuildMI(MBB, DL, TII->get(SystemZ::CLGFI))
11091 .addReg(PHIReg)
11092 .addImm(ProbeSize);
11093 BuildMI(MBB, DL, TII->get(SystemZ::BRC))
11095 .addMBB(TailTestMBB);
11096 MBB->addSuccessor(LoopBodyMBB);
11097 MBB->addSuccessor(TailTestMBB);
11098
11099 // LoopBodyMBB: Allocate and probe by means of a volatile compare.
11100 // J LoopTestMBB
11101 MBB = LoopBodyMBB;
11102 BuildMI(MBB, DL, TII->get(SystemZ::SLGFI), IncReg)
11103 .addReg(PHIReg)
11104 .addImm(ProbeSize);
11105 BuildMI(MBB, DL, TII->get(SystemZ::SLGFI), SystemZ::R15D)
11106 .addReg(SystemZ::R15D)
11107 .addImm(ProbeSize);
11108 BuildMI(MBB, DL, TII->get(SystemZ::CG)).addReg(SystemZ::R15D)
11109 .addReg(SystemZ::R15D).addImm(ProbeSize - 8).addReg(0)
11110 .setMemRefs(VolLdMMO);
11111 BuildMI(MBB, DL, TII->get(SystemZ::J)).addMBB(LoopTestMBB);
11112 MBB->addSuccessor(LoopTestMBB);
11113
11114 // TailTestMBB
11115 // BRC DoneMBB
11116 // # fallthrough to TailMBB
11117 MBB = TailTestMBB;
11118 BuildMI(MBB, DL, TII->get(SystemZ::CGHI))
11119 .addReg(PHIReg)
11120 .addImm(0);
11121 BuildMI(MBB, DL, TII->get(SystemZ::BRC))
11123 .addMBB(DoneMBB);
11124 MBB->addSuccessor(TailMBB);
11125 MBB->addSuccessor(DoneMBB);
11126
11127 // TailMBB
11128 // # fallthrough to DoneMBB
11129 MBB = TailMBB;
11130 BuildMI(MBB, DL, TII->get(SystemZ::SLGR), SystemZ::R15D)
11131 .addReg(SystemZ::R15D)
11132 .addReg(PHIReg);
11133 BuildMI(MBB, DL, TII->get(SystemZ::CG)).addReg(SystemZ::R15D)
11134 .addReg(SystemZ::R15D).addImm(-8).addReg(PHIReg)
11135 .setMemRefs(VolLdMMO);
11136 MBB->addSuccessor(DoneMBB);
11137
11138 // DoneMBB
11139 MBB = DoneMBB;
11140 BuildMI(*MBB, MBB->begin(), DL, TII->get(TargetOpcode::COPY), DstReg)
11141 .addReg(SystemZ::R15D);
11142
11143 MI.eraseFromParent();
11144 return DoneMBB;
11145}
11146
11147SDValue SystemZTargetLowering::
11148getBackchainAddress(SDValue SP, SelectionDAG &DAG) const {
11150 auto *TFL = Subtarget.getFrameLowering<SystemZELFFrameLowering>();
11151 SDLoc DL(SP);
11152 return DAG.getNode(ISD::ADD, DL, MVT::i64, SP,
11153 DAG.getIntPtrConstant(TFL->getBackchainOffset(MF), DL));
11154}
11155
11156// Replace a _STACKGUARD_DAG pseudo with a _STACKGUARD pseudo, adding
11157// a dead early-clobber def reg that will be used as a scratch register
11158// when the pseudo is expanded.
11159MachineBasicBlock *SystemZTargetLowering::emitStackGuardPseudo(
11160 MachineInstr &MI, MachineBasicBlock *MBB, unsigned PseudoOp) const {
11161 MachineRegisterInfo *MRI = &MBB->getParent()->getRegInfo();
11162 const SystemZInstrInfo *TII = Subtarget.getInstrInfo();
11163 DebugLoc DL = MI.getDebugLoc();
11164 Register AddrReg = MRI->createVirtualRegister(&SystemZ::ADDR64BitRegClass);
11165 BuildMI(*MBB, MI, DL, TII->get(PseudoOp), AddrReg)
11166 .addFrameIndex(MI.getOperand(0).getIndex())
11167 .addImm(MI.getOperand(1).getImm());
11168 MI.eraseFromParent();
11169 return MBB;
11170}
11171
11174 switch (MI.getOpcode()) {
11175 case SystemZ::ADJCALLSTACKDOWN:
11176 case SystemZ::ADJCALLSTACKUP:
11177 return emitAdjCallStack(MI, MBB);
11178
11179 case SystemZ::Select32:
11180 case SystemZ::Select64:
11181 case SystemZ::Select128:
11182 case SystemZ::SelectF32:
11183 case SystemZ::SelectF64:
11184 case SystemZ::SelectF128:
11185 case SystemZ::SelectVR32:
11186 case SystemZ::SelectVR64:
11187 case SystemZ::SelectVR128:
11188 return emitSelect(MI, MBB);
11189
11190 case SystemZ::CondStore8Mux:
11191 return emitCondStore(MI, MBB, SystemZ::STCMux, 0, false);
11192 case SystemZ::CondStore8MuxInv:
11193 return emitCondStore(MI, MBB, SystemZ::STCMux, 0, true);
11194 case SystemZ::CondStore16Mux:
11195 return emitCondStore(MI, MBB, SystemZ::STHMux, 0, false);
11196 case SystemZ::CondStore16MuxInv:
11197 return emitCondStore(MI, MBB, SystemZ::STHMux, 0, true);
11198 case SystemZ::CondStore32Mux:
11199 return emitCondStore(MI, MBB, SystemZ::STMux, SystemZ::STOCMux, false);
11200 case SystemZ::CondStore32MuxInv:
11201 return emitCondStore(MI, MBB, SystemZ::STMux, SystemZ::STOCMux, true);
11202 case SystemZ::CondStore8:
11203 return emitCondStore(MI, MBB, SystemZ::STC, 0, false);
11204 case SystemZ::CondStore8Inv:
11205 return emitCondStore(MI, MBB, SystemZ::STC, 0, true);
11206 case SystemZ::CondStore16:
11207 return emitCondStore(MI, MBB, SystemZ::STH, 0, false);
11208 case SystemZ::CondStore16Inv:
11209 return emitCondStore(MI, MBB, SystemZ::STH, 0, true);
11210 case SystemZ::CondStore32:
11211 return emitCondStore(MI, MBB, SystemZ::ST, SystemZ::STOC, false);
11212 case SystemZ::CondStore32Inv:
11213 return emitCondStore(MI, MBB, SystemZ::ST, SystemZ::STOC, true);
11214 case SystemZ::CondStore64:
11215 return emitCondStore(MI, MBB, SystemZ::STG, SystemZ::STOCG, false);
11216 case SystemZ::CondStore64Inv:
11217 return emitCondStore(MI, MBB, SystemZ::STG, SystemZ::STOCG, true);
11218 case SystemZ::CondStoreF32:
11219 return emitCondStore(MI, MBB, SystemZ::STE, 0, false);
11220 case SystemZ::CondStoreF32Inv:
11221 return emitCondStore(MI, MBB, SystemZ::STE, 0, true);
11222 case SystemZ::CondStoreF64:
11223 return emitCondStore(MI, MBB, SystemZ::STD, 0, false);
11224 case SystemZ::CondStoreF64Inv:
11225 return emitCondStore(MI, MBB, SystemZ::STD, 0, true);
11226
11227 case SystemZ::SCmp128Hi:
11228 return emitICmp128Hi(MI, MBB, false);
11229 case SystemZ::UCmp128Hi:
11230 return emitICmp128Hi(MI, MBB, true);
11231
11232 case SystemZ::PAIR128:
11233 return emitPair128(MI, MBB);
11234 case SystemZ::AEXT128:
11235 return emitExt128(MI, MBB, false);
11236 case SystemZ::ZEXT128:
11237 return emitExt128(MI, MBB, true);
11238
11239 case SystemZ::ATOMIC_SWAPW:
11240 return emitAtomicLoadBinary(MI, MBB, 0);
11241
11242 case SystemZ::ATOMIC_LOADW_AR:
11243 return emitAtomicLoadBinary(MI, MBB, SystemZ::AR);
11244 case SystemZ::ATOMIC_LOADW_AFI:
11245 return emitAtomicLoadBinary(MI, MBB, SystemZ::AFI);
11246
11247 case SystemZ::ATOMIC_LOADW_SR:
11248 return emitAtomicLoadBinary(MI, MBB, SystemZ::SR);
11249
11250 case SystemZ::ATOMIC_LOADW_NR:
11251 return emitAtomicLoadBinary(MI, MBB, SystemZ::NR);
11252 case SystemZ::ATOMIC_LOADW_NILH:
11253 return emitAtomicLoadBinary(MI, MBB, SystemZ::NILH);
11254
11255 case SystemZ::ATOMIC_LOADW_OR:
11256 return emitAtomicLoadBinary(MI, MBB, SystemZ::OR);
11257 case SystemZ::ATOMIC_LOADW_OILH:
11258 return emitAtomicLoadBinary(MI, MBB, SystemZ::OILH);
11259
11260 case SystemZ::ATOMIC_LOADW_XR:
11261 return emitAtomicLoadBinary(MI, MBB, SystemZ::XR);
11262 case SystemZ::ATOMIC_LOADW_XILF:
11263 return emitAtomicLoadBinary(MI, MBB, SystemZ::XILF);
11264
11265 case SystemZ::ATOMIC_LOADW_NRi:
11266 return emitAtomicLoadBinary(MI, MBB, SystemZ::NR, true);
11267 case SystemZ::ATOMIC_LOADW_NILHi:
11268 return emitAtomicLoadBinary(MI, MBB, SystemZ::NILH, true);
11269
11270 case SystemZ::ATOMIC_LOADW_MIN:
11271 return emitAtomicLoadMinMax(MI, MBB, SystemZ::CR, SystemZ::CCMASK_CMP_LE);
11272 case SystemZ::ATOMIC_LOADW_MAX:
11273 return emitAtomicLoadMinMax(MI, MBB, SystemZ::CR, SystemZ::CCMASK_CMP_GE);
11274 case SystemZ::ATOMIC_LOADW_UMIN:
11275 return emitAtomicLoadMinMax(MI, MBB, SystemZ::CLR, SystemZ::CCMASK_CMP_LE);
11276 case SystemZ::ATOMIC_LOADW_UMAX:
11277 return emitAtomicLoadMinMax(MI, MBB, SystemZ::CLR, SystemZ::CCMASK_CMP_GE);
11278
11279 case SystemZ::ATOMIC_CMP_SWAPW:
11280 return emitAtomicCmpSwapW(MI, MBB);
11281 case SystemZ::MVCImm:
11282 case SystemZ::MVCReg:
11283 return emitMemMemWrapper(MI, MBB, SystemZ::MVC);
11284 case SystemZ::NCImm:
11285 return emitMemMemWrapper(MI, MBB, SystemZ::NC);
11286 case SystemZ::OCImm:
11287 return emitMemMemWrapper(MI, MBB, SystemZ::OC);
11288 case SystemZ::XCImm:
11289 case SystemZ::XCReg:
11290 return emitMemMemWrapper(MI, MBB, SystemZ::XC);
11291 case SystemZ::CLCImm:
11292 case SystemZ::CLCReg:
11293 return emitMemMemWrapper(MI, MBB, SystemZ::CLC);
11294 case SystemZ::MemsetImmImm:
11295 case SystemZ::MemsetImmReg:
11296 case SystemZ::MemsetRegImm:
11297 case SystemZ::MemsetRegReg:
11298 return emitMemMemWrapper(MI, MBB, SystemZ::MVC, true/*IsMemset*/);
11299 case SystemZ::MemmoveImm:
11300 return emitMemmoveImm(MI, MBB);
11301 case SystemZ::CLSTLoop:
11302 return emitStringWrapper(MI, MBB, SystemZ::CLST);
11303 case SystemZ::MVSTLoop:
11304 return emitStringWrapper(MI, MBB, SystemZ::MVST);
11305 case SystemZ::SRSTLoop:
11306 return emitStringWrapper(MI, MBB, SystemZ::SRST);
11307 case SystemZ::TBEGIN:
11308 return emitTransactionBegin(MI, MBB, SystemZ::TBEGIN, false);
11309 case SystemZ::TBEGIN_nofloat:
11310 return emitTransactionBegin(MI, MBB, SystemZ::TBEGIN, true);
11311 case SystemZ::TBEGINC:
11312 return emitTransactionBegin(MI, MBB, SystemZ::TBEGINC, true);
11313 case SystemZ::LTEBRCompare_Pseudo:
11314 return emitLoadAndTestCmp0(MI, MBB, SystemZ::LTEBR);
11315 case SystemZ::LTDBRCompare_Pseudo:
11316 return emitLoadAndTestCmp0(MI, MBB, SystemZ::LTDBR);
11317 case SystemZ::LTXBRCompare_Pseudo:
11318 return emitLoadAndTestCmp0(MI, MBB, SystemZ::LTXBR);
11319
11320 case SystemZ::PROBED_ALLOCA:
11321 return emitProbedAlloca(MI, MBB);
11322 case SystemZ::EH_SjLj_SetJmp:
11323 return emitEHSjLjSetJmp(MI, MBB);
11324 case SystemZ::EH_SjLj_LongJmp:
11325 return emitEHSjLjLongJmp(MI, MBB);
11326
11327 case TargetOpcode::STACKMAP:
11328 case TargetOpcode::PATCHPOINT:
11329 return emitPatchPoint(MI, MBB);
11330
11331 case SystemZ::MOV_STACKGUARD_DAG:
11332 return emitStackGuardPseudo(MI, MBB, SystemZ::MOV_STACKGUARD);
11333
11334 case SystemZ::CMP_STACKGUARD_DAG:
11335 return emitStackGuardPseudo(MI, MBB, SystemZ::CMP_STACKGUARD);
11336
11337 default:
11338 llvm_unreachable("Unexpected instr type to insert");
11339 }
11340}
11341
11342// This is only used by the isel schedulers, and is needed only to prevent
11343// compiler from crashing when list-ilp is used.
11344const TargetRegisterClass *
11345SystemZTargetLowering::getRepRegClassFor(MVT VT) const {
11346 if (VT == MVT::Untyped)
11347 return &SystemZ::ADDR128BitRegClass;
11349}
11350
11351SDValue SystemZTargetLowering::lowerGET_ROUNDING(SDValue Op,
11352 SelectionDAG &DAG) const {
11353 SDLoc dl(Op);
11354 /*
11355 The rounding method is in FPC Byte 3 bits 6-7, and has the following
11356 settings:
11357 00 Round to nearest
11358 01 Round to 0
11359 10 Round to +inf
11360 11 Round to -inf
11361
11362 FLT_ROUNDS, on the other hand, expects the following:
11363 -1 Undefined
11364 0 Round to 0
11365 1 Round to nearest
11366 2 Round to +inf
11367 3 Round to -inf
11368 */
11369
11370 // Save FPC to register.
11371 SDValue Chain = Op.getOperand(0);
11372 SDValue EFPC(
11373 DAG.getMachineNode(SystemZ::EFPC, dl, {MVT::i32, MVT::Other}, Chain), 0);
11374 Chain = EFPC.getValue(1);
11375
11376 // Transform as necessary
11377 SDValue CWD1 = DAG.getNode(ISD::AND, dl, MVT::i32, EFPC,
11378 DAG.getConstant(3, dl, MVT::i32));
11379 // RetVal = (CWD1 ^ (CWD1 >> 1)) ^ 1
11380 SDValue CWD2 = DAG.getNode(ISD::XOR, dl, MVT::i32, CWD1,
11381 DAG.getNode(ISD::SRL, dl, MVT::i32, CWD1,
11382 DAG.getConstant(1, dl, MVT::i32)));
11383
11384 SDValue RetVal = DAG.getNode(ISD::XOR, dl, MVT::i32, CWD2,
11385 DAG.getConstant(1, dl, MVT::i32));
11386 RetVal = DAG.getZExtOrTrunc(RetVal, dl, Op.getValueType());
11387
11388 return DAG.getMergeValues({RetVal, Chain}, dl);
11389}
11390
11391SDValue SystemZTargetLowering::lowerVECREDUCE_ADD(SDValue Op,
11392 SelectionDAG &DAG) const {
11393 EVT VT = Op.getValueType();
11394 Op = Op.getOperand(0);
11395 EVT OpVT = Op.getValueType();
11396
11397 assert(OpVT.isVector() && "Operand type for VECREDUCE_ADD is not a vector.");
11398
11399 SDLoc DL(Op);
11400
11401 // load a 0 vector for the third operand of VSUM.
11402 SDValue Zero = DAG.getSplatBuildVector(OpVT, DL, DAG.getConstant(0, DL, VT));
11403
11404 // execute VSUM.
11405 switch (OpVT.getScalarSizeInBits()) {
11406 case 8:
11407 case 16:
11408 Op = DAG.getNode(SystemZISD::VSUM, DL, MVT::v4i32, Op, Zero);
11409 [[fallthrough]];
11410 case 32:
11411 case 64:
11412 Op = DAG.getNode(SystemZISD::VSUM, DL, MVT::i128, Op,
11413 DAG.getBitcast(Op.getValueType(), Zero));
11414 break;
11415 case 128:
11416 break; // VSUM over v1i128 should not happen and would be a noop
11417 default:
11418 llvm_unreachable("Unexpected scalar size.");
11419 }
11420 // Cast to original vector type, retrieve last element.
11421 return DAG.getNode(
11422 ISD::EXTRACT_VECTOR_ELT, DL, VT, DAG.getBitcast(OpVT, Op),
11423 DAG.getConstant(OpVT.getVectorNumElements() - 1, DL, MVT::i32));
11424}
11425
11427 FunctionType *FT = F->getFunctionType();
11428 const AttributeList &Attrs = F->getAttributes();
11429 if (Attrs.hasRetAttrs())
11430 OS << Attrs.getAsString(AttributeList::ReturnIndex) << " ";
11431 OS << *F->getReturnType() << " @" << F->getName() << "(";
11432 for (unsigned I = 0, E = FT->getNumParams(); I != E; ++I) {
11433 if (I)
11434 OS << ", ";
11435 OS << *FT->getParamType(I);
11436 AttributeSet ArgAttrs = Attrs.getParamAttrs(I);
11437 for (auto A : {Attribute::SExt, Attribute::ZExt, Attribute::NoExt})
11438 if (ArgAttrs.hasAttribute(A))
11439 OS << " " << Attribute::getNameFromAttrKind(A);
11440 }
11441 OS << ")\n";
11442}
11443
11444bool SystemZTargetLowering::isInternal(const Function *Fn) const {
11445 std::map<const Function *, bool>::iterator Itr = IsInternalCache.find(Fn);
11446 if (Itr == IsInternalCache.end())
11447 Itr = IsInternalCache
11448 .insert(std::pair<const Function *, bool>(
11449 Fn, (Fn->hasLocalLinkage() && !Fn->hasAddressTaken())))
11450 .first;
11451 return Itr->second;
11452}
11453
11454void SystemZTargetLowering::
11455verifyNarrowIntegerArgs_Call(const SmallVectorImpl<ISD::OutputArg> &Outs,
11456 const Function *F, SDValue Callee) const {
11457 // Temporarily only do the check when explicitly requested, until it can be
11458 // enabled by default.
11460 return;
11461
11462 bool IsInternal = false;
11463 const Function *CalleeFn = nullptr;
11464 if (auto *G = dyn_cast<GlobalAddressSDNode>(Callee))
11465 if ((CalleeFn = dyn_cast<Function>(G->getGlobal())))
11466 IsInternal = isInternal(CalleeFn);
11467 if (!IsInternal && !verifyNarrowIntegerArgs(Outs)) {
11468 errs() << "ERROR: Missing extension attribute of passed "
11469 << "value in call to function:\n" << "Callee: ";
11470 if (CalleeFn != nullptr)
11471 printFunctionArgExts(CalleeFn, errs());
11472 else
11473 errs() << "-\n";
11474 errs() << "Caller: ";
11476 llvm_unreachable("");
11477 }
11478}
11479
11480void SystemZTargetLowering::
11481verifyNarrowIntegerArgs_Ret(const SmallVectorImpl<ISD::OutputArg> &Outs,
11482 const Function *F) const {
11483 // Temporarily only do the check when explicitly requested, until it can be
11484 // enabled by default.
11486 return;
11487
11488 if (!isInternal(F) && !verifyNarrowIntegerArgs(Outs)) {
11489 errs() << "ERROR: Missing extension attribute of returned "
11490 << "value from function:\n";
11492 llvm_unreachable("");
11493 }
11494}
11495
11496// Verify that narrow integer arguments are extended as required by the ABI.
11497// Return false if an error is found.
11498bool SystemZTargetLowering::verifyNarrowIntegerArgs(
11499 const SmallVectorImpl<ISD::OutputArg> &Outs) const {
11500 if (!Subtarget.isTargetELF())
11501 return true;
11502
11505 return true;
11506 } else if (!getTargetMachine().Options.VerifyArgABICompliance)
11507 return true;
11508
11509 for (unsigned i = 0; i < Outs.size(); ++i) {
11510 MVT VT = Outs[i].VT;
11511 ISD::ArgFlagsTy Flags = Outs[i].Flags;
11512 if (VT.isInteger()) {
11513 assert((VT == MVT::i32 || VT.getSizeInBits() >= 64) &&
11514 "Unexpected integer argument VT.");
11515 if (VT == MVT::i32 &&
11516 !Flags.isSExt() && !Flags.isZExt() && !Flags.isNoExt())
11517 return false;
11518 }
11519 }
11520
11521 return true;
11522}
11523
11525 Module &M, const LibcallLoweringInfo &Libcalls) const {
11526 StringRef GuardMode = M.getStackProtectorGuard();
11527
11528 // In the TLS case, no symbol needs to be inserted.
11529 if (GuardMode == "tls" || GuardMode.empty())
11530 return;
11531
11532 // Otherwise (in the global case), insert the appropriate global variable.
11534}
return SDValue()
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static msgpack::DocNode getNode(msgpack::DocNode DN, msgpack::Type Type, MCValue Val)
unsigned Imm
unsigned uint64_t
AMDGPU Register Bank Select
static bool isZeroVector(SDValue N)
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis false
Function Alias Analysis Results
#define X(NUM, ENUM, NAME)
Definition ELF.h:856
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 SDValue convertValVTToLocVT(SelectionDAG &DAG, SDValue Val, const CCValAssign &VA, const SDLoc &DL)
static SDValue convertLocVTToValVT(SelectionDAG &DAG, SDValue Val, const CCValAssign &VA, const SDLoc &DL)
#define Check(C,...)
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
Module.h This file contains the declarations for the Module class.
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
#define RegName(no)
static LVOptions Options
Definition LVOptions.cpp:25
static bool isSelectPseudo(MachineInstr &MI)
#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
static bool isUndef(const MachineInstr &MI)
Register Reg
Register const TargetRegisterInfo * TRI
Promote Memory to Register
Definition Mem2Reg.cpp:110
uint64_t High
uint64_t IntrinsicInst * II
#define P(N)
static constexpr MCPhysReg SPReg
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")))
const char * Msg
This file defines the SmallSet class.
#define LLVM_DEBUG(...)
Definition Debug.h:119
static SDValue getI128Select(SelectionDAG &DAG, const SDLoc &DL, Comparison C, SDValue TrueOp, SDValue FalseOp)
static SmallVector< SDValue, 4 > simplifyAssumingCCVal(SDValue &Val, SDValue &CC, SelectionDAG &DAG)
static void adjustForTestUnderMask(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
static void printFunctionArgExts(const Function *F, raw_fd_ostream &OS)
static void adjustForLTGFR(Comparison &C)
static void adjustSubwordCmp(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
static SDValue joinDwords(SelectionDAG &DAG, const SDLoc &DL, SDValue Op0, SDValue Op1)
#define CONV(X)
static cl::opt< bool > EnableIntArgExtCheck("argext-abi-check", cl::init(false), cl::desc("Verify that narrow int args are properly extended per the " "SystemZ ABI."))
static bool isOnlyUsedByStores(SDValue StoredVal, SelectionDAG &DAG)
static void lowerGR128Binary(SelectionDAG &DAG, const SDLoc &DL, EVT VT, unsigned Opcode, SDValue Op0, SDValue Op1, SDValue &Even, SDValue &Odd)
static void adjustForRedundantAnd(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
static SDValue lowerAddrSpaceCast(SDValue Op, SelectionDAG &DAG)
static SDValue buildScalarToVector(SelectionDAG &DAG, const SDLoc &DL, EVT VT, SDValue Value)
static SDValue lowerI128ToGR128(SelectionDAG &DAG, SDValue In)
static bool isSimpleShift(SDValue N, unsigned &ShiftVal)
static SDValue mergeHighParts(SelectionDAG &DAG, const SDLoc &DL, unsigned MergedBits, EVT VT, SDValue Op0, SDValue Op1)
static bool isI128MovedToParts(LoadSDNode *LD, SDNode *&LoPart, SDNode *&HiPart)
static bool chooseShuffleOpNos(int *OpNos, unsigned &OpNo0, unsigned &OpNo1)
static uint32_t findZeroVectorIdx(SDValue *Ops, unsigned Num)
static bool isVectorElementSwap(ArrayRef< int > M, EVT VT)
static void getCSAddressAndShifts(SDValue Addr, SelectionDAG &DAG, SDLoc DL, SDValue &AlignedAddr, SDValue &BitShift, SDValue &NegBitShift)
static bool isShlDoublePermute(const SmallVectorImpl< int > &Bytes, unsigned &StartIndex, unsigned &OpNo0, unsigned &OpNo1)
static SDValue getPermuteNode(SelectionDAG &DAG, const SDLoc &DL, const Permute &P, SDValue Op0, SDValue Op1)
static SDNode * emitIntrinsicWithCCAndChain(SelectionDAG &DAG, SDValue Op, unsigned Opcode)
static SDValue getCCResult(SelectionDAG &DAG, SDValue CCReg)
static void adjustForStackGuardCompare(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
static bool isIntrinsicWithCCAndChain(SDValue Op, unsigned &Opcode, unsigned &CCValid)
static void lowerMUL_LOHI32(SelectionDAG &DAG, const SDLoc &DL, unsigned Extend, SDValue Op0, SDValue Op1, SDValue &Hi, SDValue &Lo)
static bool isF128MovedToParts(LoadSDNode *LD, SDNode *&LoPart, SDNode *&HiPart)
static void createPHIsForSelects(SmallVector< MachineInstr *, 8 > &Selects, MachineBasicBlock *TrueMBB, MachineBasicBlock *FalseMBB, MachineBasicBlock *SinkMBB)
static SDValue getGeneralPermuteNode(SelectionDAG &DAG, const SDLoc &DL, SDValue *Ops, const SmallVectorImpl< int > &Bytes)
static unsigned getVectorComparisonOrInvert(ISD::CondCode CC, CmpMode Mode, bool &Invert)
static unsigned CCMaskForCondCode(ISD::CondCode CC)
static void adjustICmpTruncate(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
static void adjustForFNeg(Comparison &C)
static bool isScalarToVector(SDValue Op)
static SDValue emitSETCC(SelectionDAG &DAG, const SDLoc &DL, SDValue CCReg, unsigned CCValid, unsigned CCMask)
static bool matchPermute(const SmallVectorImpl< int > &Bytes, const Permute &P, unsigned &OpNo0, unsigned &OpNo1)
static bool isAddCarryChain(SDValue Carry)
static SDValue emitCmp(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
static MachineOperand earlyUseOperand(MachineOperand Op)
static bool canUseSiblingCall(const CCState &ArgCCInfo, SmallVectorImpl< CCValAssign > &ArgLocs, SmallVectorImpl< ISD::OutputArg > &Outs)
static bool getzOSCalleeAndADA(SelectionDAG &DAG, SDValue &Callee, SDValue &ADA, SDLoc &DL, SDValue &Chain)
static SDValue convertToF16(SDValue Op, SelectionDAG &DAG)
static bool combineCCMask(SDValue &CCReg, int &CCValid, int &CCMask, SelectionDAG &DAG)
static bool shouldSwapCmpOperands(const Comparison &C)
static bool isNaturalMemoryOperand(SDValue Op, unsigned ICmpType)
static SDValue getADAEntry(SelectionDAG &DAG, SDValue Val, SDLoc DL, unsigned Offset, bool LoadAdr=false)
static SDNode * emitIntrinsicWithCC(SelectionDAG &DAG, SDValue Op, unsigned Opcode)
static void adjustForSubtraction(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
static bool getVPermMask(SDValue ShuffleOp, SmallVectorImpl< int > &Bytes)
static const Permute PermuteForms[]
static bool isI128MovedFromParts(SDValue Val, SDValue &LoPart, SDValue &HiPart)
static std::pair< SDValue, int > findCCUse(const SDValue &Val, unsigned Depth=0)
static bool isSubBorrowChain(SDValue Carry)
static void adjustICmp128(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
static bool analyzeArgSplit(const SmallVectorImpl< ArgTy > &Args, SmallVector< CCValAssign, 16 > &ArgLocs, unsigned I, MVT &PartVT, unsigned &NumParts)
static APInt getDemandedSrcElements(SDValue Op, const APInt &DemandedElts, unsigned OpNo)
static SDValue getAbsolute(SelectionDAG &DAG, const SDLoc &DL, SDValue Op, bool IsNegative)
static unsigned computeNumSignBitsBinOp(SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth, unsigned OpNo)
static SDValue expandBitCastI128ToF128(SelectionDAG &DAG, SDValue Src, const SDLoc &SL)
static SDValue tryBuildVectorShuffle(SelectionDAG &DAG, BuildVectorSDNode *BVN)
static SDValue convertFromF16(SDValue Op, SDLoc DL, SelectionDAG &DAG)
static unsigned getVectorComparison(ISD::CondCode CC, CmpMode Mode)
static SDValue lowerGR128ToI128(SelectionDAG &DAG, SDValue In)
static SDValue MergeInputChains(SDNode *N1, SDNode *N2)
static SDValue expandBitCastF128ToI128(SelectionDAG &DAG, SDValue Src, const SDLoc &SL)
static unsigned getTestUnderMaskCond(unsigned BitSize, unsigned CCMask, uint64_t Mask, uint64_t CmpVal, unsigned ICmpType)
static bool isIntrinsicWithCC(SDValue Op, unsigned &Opcode, unsigned &CCValid)
static SDValue expandV4F32ToV2F64(SelectionDAG &DAG, int Start, const SDLoc &DL, SDValue Op, SDValue Chain)
static Comparison getCmp(SelectionDAG &DAG, SDValue CmpOp0, SDValue CmpOp1, ISD::CondCode Cond, const SDLoc &DL, SDValue Chain=SDValue(), bool IsSignaling=false)
static bool checkCCKill(MachineInstr &MI, MachineBasicBlock *MBB)
static Register forceReg(MachineInstr &MI, MachineOperand &Base, const SystemZInstrInfo *TII)
static bool is32Bit(EVT VT)
static std::pair< unsigned, const TargetRegisterClass * > parseRegisterNumber(StringRef Constraint, const TargetRegisterClass *RC, const unsigned *Map, unsigned Size)
static unsigned detectEvenOddMultiplyOperand(const SelectionDAG &DAG, const SystemZSubtarget &Subtarget, SDValue &Op)
static bool matchDoublePermute(const SmallVectorImpl< int > &Bytes, const Permute &P, SmallVectorImpl< int > &Transform)
static Comparison getIntrinsicCmp(SelectionDAG &DAG, unsigned Opcode, SDValue Call, unsigned CCValid, uint64_t CC, ISD::CondCode Cond)
static SDValue buildFPVecFromScalars4(SelectionDAG &DAG, const SDLoc &DL, EVT VT, SmallVectorImpl< SDValue > &Elems, unsigned Pos)
static bool isAbsolute(SDValue CmpOp, SDValue Pos, SDValue Neg)
static AddressingMode getLoadStoreAddrMode(bool HasVector, Type *Ty)
static SDValue buildMergeScalars(SelectionDAG &DAG, const SDLoc &DL, EVT VT, SDValue Op0, SDValue Op1)
static void computeKnownBitsBinOp(const SDValue Op, KnownBits &Known, const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth, unsigned OpNo)
static bool getShuffleInput(const SmallVectorImpl< int > &Bytes, unsigned Start, unsigned BytesPerElement, int &Base)
static AddressingMode supportedAddressingMode(Instruction *I, bool HasVector)
static bool isF128MovedFromParts(SDValue Val, SDValue &LoPart, SDValue &HiPart)
static void adjustZeroCmp(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
Value * RHS
Value * LHS
BinaryOperator * Mul
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:231
LLVM_ABI APInt zext(unsigned width) const
Zero extend to a new width.
Definition APInt.cpp:1056
static APInt getSignMask(unsigned BitWidth)
Get the SignMask for a specific bit width.
Definition APInt.h:226
uint64_t getZExtValue() const
Get zero extended value.
Definition APInt.h:1561
unsigned getActiveBits() const
Compute the number of active bits in the value.
Definition APInt.h:1533
LLVM_ABI APInt trunc(unsigned width) const
Truncate to new width.
Definition APInt.cpp:969
void setBit(unsigned BitPosition)
Set the given bit to 1 whose position is given as "bitPosition".
Definition APInt.h:1351
static APInt getBitsSet(unsigned numBits, unsigned loBit, unsigned hiBit)
Get a value with a block of bits set.
Definition APInt.h:255
unsigned getBitWidth() const
Return the number of bits in the APInt.
Definition APInt.h:1509
bool isSingleWord() const
Determine if this APInt just has one word to store value.
Definition APInt.h:319
LLVM_ABI void insertBits(const APInt &SubBits, unsigned bitPosition)
Insert the bits from a smaller APInt starting at bitPosition.
Definition APInt.cpp:393
bool isSubsetOf(const APInt &RHS) const
This operation checks that all bits set in this APInt are also set in RHS.
Definition APInt.h:1262
void lshrInPlace(unsigned ShiftAmt)
Logical right-shift this APInt by ShiftAmt in place.
Definition APInt.h:861
APInt lshr(unsigned shiftAmt) const
Logical right-shift function.
Definition APInt.h:854
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
an instruction that atomically reads a memory location, combines it with another value,...
@ Add
*p = old + v
@ Sub
*p = old - v
@ And
*p = old & v
@ Xor
*p = old ^ v
BinOp getOperation() const
This class holds the attributes for a particular argument, parameter, function, or return value.
Definition Attributes.h:407
LLVM_ABI bool hasAttribute(Attribute::AttrKind Kind) const
Return true if the attribute exists in this set.
LLVM_ABI StringRef getValueAsString() const
Return the attribute's value as a string.
static LLVM_ABI StringRef getNameFromAttrKind(Attribute::AttrKind AttrKind)
LLVM Basic Block Representation.
Definition BasicBlock.h:62
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 bool isConstant() const
CCState - This class holds information needed while lowering arguments and return values.
LLVM_ABI void AnalyzeCallResult(const SmallVectorImpl< ISD::InputArg > &Ins, CCAssignFn Fn)
AnalyzeCallResult - Analyze the return values of a call, incorporating info about the passed values i...
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...
LLVM_ABI void AnalyzeCallOperands(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)
AnalyzeCallOperands - Analyze the outgoing arguments to a call, incorporating info about the passed v...
uint64_t getStackSize() const
Returns the size of the currently allocated portion of the stack.
LLVM_ABI void AnalyzeFormalArguments(const SmallVectorImpl< ISD::InputArg > &Ins, CCAssignFn Fn)
AnalyzeFormalArguments - Analyze an array of argument values, incorporating info about the formals in...
CCValAssign - Represent assignment of one arg/retval to a location.
Register getLocReg() const
LocInfo getLocInfo() const
bool needsCustom() const
bool isExtInLoc() const
int64_t getLocMemOffset() const
This class represents a function call, abstracting a target machine's calling convention.
bool isTailCall() const
MachineConstantPoolValue * getMachineCPVal() const
const Constant * getConstVal() const
uint64_t getZExtValue() 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
A debug info location.
Definition DebugLoc.h:126
iterator find(const_arg_type_t< KeyT > Val)
Definition DenseMap.h:223
iterator end()
Definition DenseMap.h:141
bool hasAddressTaken(const User **=nullptr, bool IgnoreCallbackUses=false, bool IgnoreAssumeLikeCalls=true, bool IngoreLLVMUsed=false, bool IgnoreARCAttachedCall=false, bool IgnoreCastedDirectCall=false) const
hasAddressTaken - returns true if there are any uses of this function other than direct calls or invo...
Definition Function.cpp:937
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
Definition Function.cpp:762
uint64_t getFnAttributeAsParsedInteger(StringRef Kind, uint64_t Default=0) const
For a string attribute Kind, parse attribute as an integer.
Definition Function.cpp:774
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
Definition Function.h:272
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition Function.cpp:727
LLVM_ABI const GlobalObject * getAliaseeObject() const
Definition Globals.cpp:730
bool hasLocalLinkage() const
bool hasPrivateLinkage() const
bool hasInternalLinkage() const
A wrapper class for inspecting calls to intrinsic functions.
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:68
Tracks which library functions to use for a particular subtarget or function.
An instruction for reading from memory.
This class is used to represent ISD::LOAD nodes.
const SDValue & getBasePtr() const
Machine Value Type.
static auto integer_fixedlen_vector_valuetypes()
SimpleValueType SimpleTy
uint64_t getScalarSizeInBits() const
bool isVector() const
Return true if this is a vector value type.
bool isInteger() const
Return true if this is an integer or a vector integer type.
static auto integer_valuetypes()
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
static auto fixedlen_vector_valuetypes()
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
static MVT getVectorVT(MVT VT, unsigned NumElements)
static MVT getIntegerVT(unsigned BitWidth)
static auto fp_valuetypes()
LLVM_ABI void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
LLVM_ABI void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
LLVM_ABI iterator getFirstNonPHI()
Returns a pointer to the first instruction in this block that is not a PHINode instruction.
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.
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
void setMachineBlockAddressTaken()
Set this block to indicate that its address is used as something other than the target of a terminato...
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
void setMaxCallFrameSize(uint64_t S)
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.
void setFrameAddressIsTaken(bool T)
uint64_t getMaxCallFrameSize() const
Return the maximum size of a call frame that must be allocated for an outgoing function call.
void setReturnAddressIsTaken(bool s)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
void push_back(MachineBasicBlock *MBB)
reverse_iterator rbegin()
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...
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 MachineInstrBuilder & setMemRefs(ArrayRef< MachineMemOperand * > MMOs) const
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 & addRegMask(const uint32_t *Mask) const
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
Representation of each machine instruction.
bool killsRegister(Register Reg, const TargetRegisterInfo *TRI) const
Return true if the MachineInstr kills the specified register.
const MachineOperand & getOperand(unsigned i) const
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.
@ MOInvariant
The memory access always returns the same value (or traps).
@ MOStore
The memory access writes data.
Flags getFlags() const
Return the raw flags of the source value,.
MachineOperand class - Representation of each machine instruction operand.
int64_t getImm() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
Register getReg() const
getReg - Returns the register number.
LLVM_ABI bool isIdenticalTo(const MachineOperand &Other) const
Returns true if this operand is identical to the specified operand except for liveness related flags ...
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,...
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
void addLiveIn(MCRegister Reg, Register vreg=Register())
addLiveIn - Add the specified register as a live-in.
Align getBaseAlign() const
Returns alignment and volatility of the memory access.
MachineMemOperand * getMemOperand() const
Return the unique MachineMemOperand object describing the memory reference performed by operation.
const MachinePointerInfo & getPointerInfo() const
const SDValue & getChain() const
EVT getMemoryVT() const
Return the type of the in-memory value.
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:67
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...
Represents one node in the SelectionDAG.
bool isMachineOpcode() const
Test if this node has a post-isel opcode, directly corresponding to a MachineInstr opcode.
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.
SDNodeFlags getFlags() const
uint64_t getAsZExtVal() const
Helper method returns the zero-extended integer value of a ConstantSDNode.
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.
unsigned getMachineOpcode() const
This may only be called if isMachineOpcode returns true.
const SDValue & getOperand(unsigned Num) const
bool hasNUsesOfValue(unsigned NUses, unsigned Value) const
Return true if there are exactly NUSES uses of the indicated value.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
iterator_range< user_iterator > users()
void setFlags(SDNodeFlags NewFlags)
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.
bool isMachineOpcode() const
TypeSize getValueSizeInBits() const
Returns the size of the value in bits.
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
MVT getSimpleValueType() const
Return the simple ValueType of the referenced return value.
unsigned getMachineOpcode() const
unsigned getOpcode() 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)
SDValue getExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT, unsigned Opcode)
Convert Op, which must be of integer type, to the integer type VT, by either any/sign/zero-extending ...
LLVM_ABI SDValue getAddrSpaceCast(const SDLoc &dl, EVT VT, SDValue Ptr, unsigned SrcAS, unsigned DestAS)
Return an AddrSpaceCastSDNode.
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 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 SDValue getAtomicLoad(ISD::LoadExtType ExtType, const SDLoc &dl, EVT MemVT, EVT VT, SDValue Chain, SDValue Ptr, MachineMemOperand *MMO)
LLVM_ABI SDValue getConstantPool(const Constant *C, EVT VT, MaybeAlign Align=std::nullopt, int Offs=0, bool isT=false, unsigned TargetFlags=0)
LLVM_ABI bool isConstantIntBuildVectorOrConstantInt(SDValue N, bool AllowOpaques=true) const
Test whether the given value is a constant int or similar node.
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 SDValue getRegister(Register Reg, EVT VT)
SDValue getGLOBAL_OFFSET_TABLE(EVT VT)
Return a GLOBAL_OFFSET_TABLE node. This does not have a useful SDLoc.
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.
LLVM_ABI SDValue getAtomic(unsigned Opcode, const SDLoc &dl, EVT MemVT, SDValue Chain, SDValue Ptr, SDValue Val, MachineMemOperand *MMO)
Gets a node for an atomic op, produces result (if relevant) and chain and takes 2 operands.
void addNoMergeSiteInfo(const SDNode *Node, bool NoMerge)
Set NoMergeSiteInfo to be associated with Node if NoMerge is true.
LLVM_ABI SDValue getNOT(const SDLoc &DL, SDValue Val, EVT VT)
Create a bitwise NOT operation as (XOR Val, -1).
LLVM_ABI SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align DstAlign, Align SrcAlign, bool isVol, bool AlwaysInline, const CallInst *CI, std::optional< bool > OverrideTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes(), BatchAAResults *BatchAA=nullptr)
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 bool isSplatValue(SDValue V, const APInt &DemandedElts, APInt &UndefElts, unsigned Depth=0) const
Test whether V has a splatted value for all the demanded elements.
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)
const DataLayout & getDataLayout() const
SDValue getTargetFrameIndex(int FI, EVT VT)
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 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 SDValue getSignedConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
SDValue getSplatVector(EVT VT, const SDLoc &DL, SDValue Op)
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 bool SignBitIsZero(SDValue Op, unsigned Depth=0) const
Return true if the sign bit of Op is known to be zero.
LLVM_ABI SDValue getTargetExtractSubreg(int SRIdx, const SDLoc &DL, EVT VT, SDValue Operand)
A convenience function for creating TargetInstrInfo::EXTRACT_SUBREG nodes.
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 SDValue getExternalSymbol(const char *Sym, EVT VT)
const TargetMachine & getTarget() const
LLVM_ABI std::pair< SDValue, SDValue > getStrictFPExtendOrRound(SDValue Op, SDValue Chain, const SDLoc &DL, EVT VT)
Convert Op, which must be a STRICT operation of float type, to the float type VT, by either extending...
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 SDValue getFPExtendOrRound(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of float type, to the float type VT, by either extending or rounding (by tr...
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.
SDValue getTargetBlockAddress(const BlockAddress *BA, EVT VT, int64_t Offset=0, unsigned TargetFlags=0)
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 getSplatBuildVector(EVT VT, const SDLoc &DL, SDValue Op)
Return a splat ISD::BUILD_VECTOR node, consisting of Op splatted to all elements.
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 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.
LLVM_ABI SDNode * UpdateNodeOperands(SDNode *N, SDValue Op)
Mutate the specified node in-place to have the specified operands.
SDValue getTargetConstantPool(const Constant *C, EVT VT, MaybeAlign Align=std::nullopt, int Offset=0, unsigned TargetFlags=0)
LLVM_ABI SDValue getTargetInsertSubreg(int SRIdx, const SDLoc &DL, EVT VT, SDValue Operand, SDValue Subreg)
A convenience function for creating TargetInstrInfo::INSERT_SUBREG nodes.
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
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.
This SDNode is used to implement the code generator support for the llvm IR shufflevector instruction...
ArrayRef< int > getMask() const
const_iterator begin() const
Definition SmallSet.h:216
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
size_type size() const
Definition SmallSet.h:171
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void resize(size_type N)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
This class is used to represent ISD::STORE nodes.
const SDValue & getBasePtr() const
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
Definition StringRef.h:490
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition StringRef.h:258
constexpr bool empty() const
Check if the string is empty.
Definition StringRef.h:141
StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
Definition StringRef.h:720
constexpr size_t size() const
Get the string size.
Definition StringRef.h:144
iterator end() const
Definition StringRef.h:116
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
A SystemZ-specific class detailing special use registers particular for calling conventions.
static SystemZConstantPoolValue * Create(const GlobalValue *GV, SystemZCP::SystemZCPModifier Modifier)
const SystemZInstrInfo * getInstrInfo() const override
SystemZCallingConventionRegisters * getSpecialRegisters() const
AtomicExpansionKind shouldExpandAtomicRMWInIR(const AtomicRMWInst *RMW) const override
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
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...
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,...
bool hasInlineStackProbe(const MachineFunction &MF) const override
Returns true if stack probing through inline assembly is requested.
MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *BB) const override
This method should be implemented by targets that mark instructions with the 'usesCustomInserter' fla...
MachineBasicBlock * emitEHSjLjSetJmp(MachineInstr &MI, MachineBasicBlock *MBB) const
AtomicExpansionKind shouldCastAtomicLoadInIR(LoadInst *LI) const override
Returns how the given (atomic) load should be cast by the IR-level AtomicExpand pass.
EVT getSetCCResultType(const DataLayout &DL, LLVMContext &, EVT) const override
Return the ValueType of the result of SETCC operations.
bool allowTruncateForTailCall(Type *, Type *) const override
Return true if a truncation from FromTy to ToTy is permitted when deciding whether a call is in tail ...
SDValue LowerAsmOutputForConstraint(SDValue &Chain, SDValue &Flag, const SDLoc &DL, const AsmOperandInfo &Constraint, SelectionDAG &DAG) const override
SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, const SmallVectorImpl< ISD::OutputArg > &Outs, const SmallVectorImpl< SDValue > &OutVals, const SDLoc &DL, SelectionDAG &DAG) const override
This hook must be implemented to lower outgoing return values, described by the Outs array,...
MVT getRegisterTypeForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT) const override
Certain combinations of ABIs, Targets and features require that types are legal for some operations a...
MachineBasicBlock * emitEHSjLjLongJmp(MachineInstr &MI, MachineBasicBlock *MBB) const
bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, bool isVarArg, const SmallVectorImpl< ISD::OutputArg > &Outs, LLVMContext &Context, const Type *RetTy) const override
This hook should be implemented to check whether the return values described by the Outs array can fi...
std::pair< SDValue, SDValue > makeExternalCall(SDValue Chain, SelectionDAG &DAG, const char *CalleeName, EVT RetVT, ArrayRef< SDValue > Ops, CallingConv::ID CallConv, bool IsSigned, SDLoc DL, bool DoesNotReturn, bool IsReturnValueUsed) const
void insertSSPDeclarations(Module &M, const LibcallLoweringInfo &Libcalls) const override
Insert SSP declaration if global stack protector is used.
bool mayBeEmittedAsTailCall(const CallInst *CI) const override
Return true if the target may be able emit the call instruction as a tail call.
bool splitValueIntoRegisterParts(SelectionDAG &DAG, const SDLoc &DL, SDValue Val, SDValue *Parts, unsigned NumParts, MVT PartVT, std::optional< CallingConv::ID > CC) const override
Target-specific splitting of values into parts that fit a register storing a legal type.
bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty, unsigned AS, Instruction *I=nullptr) const override
Return true if the addressing mode represented by AM is legal for this target, for a load/store of th...
unsigned getNumRegistersForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT) const override
Certain targets require unusual breakdowns of certain types.
bool isGuaranteedNotToBeUndefOrPoisonForTargetNode(SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG, UndefPoisonKind Kind, unsigned Depth) const override
Return true if this function can prove that Op is never poison and, Kind can be used to track poison ...
SystemZTargetLowering(const TargetMachine &TM, const SystemZSubtarget &STI)
bool isFMAFasterThanFMulAndFAdd(const MachineFunction &MF, EVT VT) const override
Return true if an FMA operation is faster than a pair of fmul and fadd instructions.
bool isLegalICmpImmediate(int64_t Imm) const override
Return true if the specified immediate is legal icmp immediate, that is the target has icmp instructi...
std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const override
Given a physical register constraint (e.g.
TargetLowering::ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const override
Examine constraint string and operand type and determine a weight value.
bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AS, Align Alignment, MachineMemOperand::Flags Flags, unsigned *Fast) const override
Determine if the target supports unaligned memory accesses.
const MCPhysReg * getScratchRegisters(CallingConv::ID CC) const override
Returns a 0 terminated array of registers that can be safely used as scratch registers.
TargetLowering::ConstraintType getConstraintType(StringRef Constraint) const override
Given a constraint, return the type of constraint it is for this target.
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...
bool isFPImmLegal(const APFloat &Imm, EVT VT, bool ForCodeSize) const override
Returns true if the target can instruction select the specified FP immediate natively.
SDValue joinRegisterPartsIntoValue(SelectionDAG &DAG, const SDLoc &DL, const SDValue *Parts, unsigned NumParts, MVT PartVT, EVT ValueVT, std::optional< CallingConv::ID > CC) const override
Target-specific combining of register parts into its original value.
bool isTruncateFree(Type *, Type *) const override
Return true if it's free to truncate a value of type FromTy to type ToTy.
SDValue useLibCall(SelectionDAG &DAG, RTLIB::Libcall LC, MVT VT, SDValue Arg, SDLoc DL, SDValue Chain, bool IsStrict) const
unsigned ComputeNumSignBitsForTargetNode(SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth) const override
Determine the number of bits in the operation that are sign bits.
void LowerOperationWrapper(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG) const override
This callback is invoked by the type legalizer to legalize nodes with an illegal operand type but leg...
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...
SDValue LowerCall(CallLoweringInfo &CLI, SmallVectorImpl< SDValue > &InVals) const override
This hook must be implemented to lower calls into the specified DAG.
bool isLegalAddImmediate(int64_t Imm) const override
Return true if the specified immediate is legal add immediate, that is the target has add instruction...
CondMergingParams getJumpConditionMergingParams(Instruction::BinaryOps Opc, const Value *Lhs, const Value *Rhs, const Function *F) const override
bool findOptimalMemOpLowering(LLVMContext &Context, std::vector< EVT > &MemOps, unsigned Limit, const MemOp &Op, unsigned DstAS, unsigned SrcAS, const AttributeList &FuncAttributes, EVT *LargestVT=nullptr) const override
Determines the optimal series of memory ops to replace the memset / memcpy.
void ReplaceNodeResults(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG) const override
This callback is invoked when a node result type is illegal for the target, and the operation was reg...
void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const override
Lower the specified operand into the Ops vector.
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 ...
unsigned getVectorTypeBreakdownForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT, EVT &IntermediateVT, unsigned &NumIntermediates, MVT &RegisterVT) const override
Certain targets such as MIPS require that some types such as vectors are always broken down into scal...
AtomicExpansionKind shouldCastAtomicStoreInIR(StoreInst *SI) const override
Returns how the given (atomic) store should be cast by the IR-level AtomicExpand pass into.
Register getRegisterByName(const char *RegName, LLT VT, const MachineFunction &MF) const override
Return the register ID of the name passed in.
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...
SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl< ISD::InputArg > &Ins, const SDLoc &DL, SelectionDAG &DAG, SmallVectorImpl< SDValue > &InVals) const override
This hook must be implemented to lower the incoming (formal) arguments, described by the Ins array,...
void computeKnownBitsForTargetNode(const SDValue Op, KnownBits &Known, const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth=0) const override
Determine which of the bits specified in Mask are known to be either zero or one and return them in t...
unsigned getStackProbeSize(const MachineFunction &MF) const
XPLINK64 calling convention specific use registers Particular to z/OS when in 64 bit mode.
Information about stack frame layout on the target.
unsigned getStackAlignment() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
bool hasFP(const MachineFunction &MF) const
hasFP - Return true if the specified function should have a dedicated frame pointer register.
TargetInstrInfo - Interface to description of machine instruction set.
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...
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.
MachineBasicBlock * emitPatchPoint(MachineInstr &MI, MachineBasicBlock *MBB) const
Replace/modify any TargetFrameIndex operands with a targte-dependent sequence of memory operands that...
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
const TargetMachine & getTargetMachine() const
virtual unsigned getNumRegistersForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT) const
Certain targets require unusual breakdowns of certain types.
virtual MVT getRegisterTypeForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT) const
Certain combinations of ABIs, Targets and features require that types are legal for some operations a...
virtual void insertSSPDeclarations(Module &M, const LibcallLoweringInfo &Libcalls) const
Inserts necessary declarations for SSP (stack protection) purpose.
void setMaxAtomicSizeInBitsSupported(unsigned SizeInBits)
Set the maximum atomic operation size supported by the backend.
void setAtomicLoadExtAction(unsigned ExtType, MVT ValVT, MVT MemVT, LegalizeAction Action)
Let target indicate that an extending atomic load of the specified type is legal.
virtual unsigned getVectorTypeBreakdownForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT, EVT &IntermediateVT, unsigned &NumIntermediates, MVT &RegisterVT) const
Certain targets such as MIPS require that some types such as vectors are always broken down into scal...
Register getStackPointerRegisterToSaveRestore() const
If a physical register, this specifies the register that llvm.savestack/llvm.restorestack should save...
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.
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.
bool isOperationLegal(unsigned Op, EVT VT) const
Return true if the specified operation is legal on this target.
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 const TargetRegisterClass * getRepRegClassFor(MVT VT) const
Return the 'representative' register class for the specified value type.
void setStackPointerRegisterToSaveRestore(Register R)
If set to a physical register, this specifies the register that llvm.savestack/llvm....
AtomicExpansionKind
Enum that specifies what an atomic load/AtomicRMWInst is expanded to, if at all.
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...
virtual bool shouldSignExtendTypeInLibCall(Type *Ty, bool IsSigned) const
Returns true if arguments should be sign-extended in lib calls.
std::vector< ArgListEntry > ArgListTy
unsigned MaxStoresPerMemcpy
Specify maximum number of store instructions per memcpy call.
virtual MVT getPointerMemTy(const DataLayout &DL, uint32_t AS=0) const
Return the in-memory pointer type for the given address space, defaults to the pointer type from the ...
void setSchedulingPreference(Sched::Preference Pref)
Specify the target scheduling preference.
LegalizeAction getOperationAction(unsigned Op, EVT VT) const
Return how this operation should be treated: either it is legal, needs to be promoted to a larger siz...
virtual ConstraintType getConstraintType(StringRef Constraint) const
Given a constraint, return the type of constraint it is for this target.
virtual bool findOptimalMemOpLowering(LLVMContext &Context, std::vector< EVT > &MemOps, unsigned Limit, const MemOp &Op, unsigned DstAS, unsigned SrcAS, const AttributeList &FuncAttributes, EVT *LargestVT=nullptr) const
Determines the optimal series of memory ops to replace the memset / memcpy.
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.
virtual ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const
Examine constraint string and operand type and determine a weight value.
virtual std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const
Given a physical register constraint (e.g.
TargetLowering(const TargetLowering &)=delete
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).
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.
bool useEmulatedTLS() const
Returns true if this target uses emulated TLS.
unsigned getPointerSize(unsigned AS) const
Get the pointer size for this target.
CodeModel::Model getCodeModel() const
Returns the code model.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetInstrInfo * getInstrInfo() const
static constexpr TypeSize getFixed(ScalarTy ExactSize)
Definition TypeSize.h:343
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
bool isVectorTy() const
True if this is an instance of VectorType.
Definition Type.h:288
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
Definition Type.cpp:197
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
Definition Type.cpp:232
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
Definition Type.h:186
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:257
A Use represents the edge between a Value definition and its users.
Definition Use.h:35
User * getUser() const
Returns the User that contains this Use.
Definition Use.h:61
Value * getOperand(unsigned i) const
Definition User.h:207
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:255
user_iterator user_begin()
Definition Value.h:402
bool hasOneUse() const
Return true if there is exactly one use of this value.
Definition Value.h:439
int getNumOccurrences() const
constexpr ScalarTy getFixedValue() const
Definition TypeSize.h:200
A raw_ostream that writes to a file descriptor.
CallInst * Call
#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 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.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
@ GHC
Used by the Glasgow Haskell Compiler (GHC).
Definition CallingConv.h:50
@ 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.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
Definition ISDOpcodes.h:829
@ MERGE_VALUES
MERGE_VALUES - This node takes multiple discrete operands and returns them all as its individual resu...
Definition ISDOpcodes.h:261
@ STACKRESTORE
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain.
@ STACKSAVE
STACKSAVE - STACKSAVE has one operand, an input chain.
@ STRICT_FSETCC
STRICT_FSETCC/STRICT_FSETCCS - Constrained versions of SETCC, used for floating-point operands only.
Definition ISDOpcodes.h:513
@ POISON
POISON - A poison node.
Definition ISDOpcodes.h:236
@ EH_SJLJ_LONGJMP
OUTCHAIN = EH_SJLJ_LONGJMP(INCHAIN, buffer) This corresponds to the eh.sjlj.longjmp intrinsic.
Definition ISDOpcodes.h:168
@ 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
@ BSWAP
Byte Swap and Counting operators.
Definition ISDOpcodes.h:789
@ VAEND
VAEND, VASTART - VAEND and VASTART have three operands: an input chain, pointer, and a SRCVALUE.
@ ATOMIC_STORE
OUTCHAIN = ATOMIC_STORE(INCHAIN, val, ptr) This corresponds to "store atomic" instruction.
@ 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...
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
Definition ISDOpcodes.h:863
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
Definition ISDOpcodes.h:520
@ PSEUDO_FMIN
PSEUDO_FMIN is strictly equivalent to op0 olt op1 ?
@ INTRINSIC_VOID
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
Definition ISDOpcodes.h:220
@ GlobalAddress
Definition ISDOpcodes.h:88
@ ATOMIC_CMP_SWAP_WITH_SUCCESS
Val, Success, OUTCHAIN = ATOMIC_CMP_SWAP_WITH_SUCCESS(INCHAIN, ptr, cmp, swap) N.b.
@ STRICT_FMINIMUM
Definition ISDOpcodes.h:473
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
Definition ISDOpcodes.h:890
@ FADD
Simple binary floating point operators.
Definition ISDOpcodes.h:417
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
Definition ISDOpcodes.h:749
@ MEMBARRIER
MEMBARRIER - Compiler barrier only; generate a no-op.
@ ATOMIC_FENCE
OUTCHAIN = ATOMIC_FENCE(INCHAIN, ordering, scope) This corresponds to the fence instruction.
@ SIGN_EXTEND_VECTOR_INREG
SIGN_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register sign-extension of the low ...
Definition ISDOpcodes.h:920
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
Definition ISDOpcodes.h:280
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ STRICT_PSEUDO_FMAX
Definition ISDOpcodes.h:462
@ BUILD_PAIR
BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.
Definition ISDOpcodes.h:254
@ STRICT_FSQRT
Constrained versions of libm-equivalent floating point intrinsics.
Definition ISDOpcodes.h:438
@ BUILTIN_OP_END
BUILTIN_OP_END - This must be the last enum value in this list.
@ GlobalTLSAddress
Definition ISDOpcodes.h:89
@ CTLZ_ZERO_POISON
Definition ISDOpcodes.h:798
@ SIGN_EXTEND
Conversion operators.
Definition ISDOpcodes.h:854
@ STRICT_UINT_TO_FP
Definition ISDOpcodes.h:487
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
Definition ISDOpcodes.h:667
@ PREFETCH
PREFETCH - This corresponds to a prefetch intrinsic.
@ STRICT_PSEUDO_FMIN
Definition ISDOpcodes.h:461
@ FSINCOS
FSINCOS - Compute both fsin and fcos as a single operation.
@ FNEG
Perform various unary floating-point operations inspired by libm.
@ BR_CC
BR_CC - Conditional branch.
@ SSUBO
Same for subtraction.
Definition ISDOpcodes.h:352
@ BR_JT
BR_JT - Jumptable branch.
@ IS_FPCLASS
Performs a check of floating point class property, defined by IEEE-754.
Definition ISDOpcodes.h:550
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
Definition ISDOpcodes.h:806
@ ATOMIC_LOAD
Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) This corresponds to "load atomic" instruction.
@ UNDEF
UNDEF - An undefined node.
Definition ISDOpcodes.h:233
@ EXTRACT_ELEMENT
EXTRACT_ELEMENT - This is used to get the lower or upper (determined by a Constant,...
Definition ISDOpcodes.h:247
@ SPLAT_VECTOR
SPLAT_VECTOR(VAL) - Returns a vector with the scalar value VAL duplicated in all lanes.
Definition ISDOpcodes.h:674
@ VACOPY
VACOPY - VACOPY has 5 operands: an input chain, a destination pointer, a source pointer,...
@ SADDO
RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
Definition ISDOpcodes.h:348
@ VECREDUCE_ADD
Integer reductions may have a result type larger than the vector element type.
@ GET_ROUNDING
Returns current rounding mode: -1 Undefined 0 Round to 0 1 Round to nearest, ties to even 2 Round to ...
Definition ISDOpcodes.h:980
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
Definition ISDOpcodes.h:706
@ SHL
Shift and rotation operations.
Definition ISDOpcodes.h:771
@ VECTOR_SHUFFLE
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
Definition ISDOpcodes.h:651
@ STRICT_FMAXIMUM
Definition ISDOpcodes.h:472
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
Definition ISDOpcodes.h:578
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
Definition ISDOpcodes.h:860
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
Definition ISDOpcodes.h:821
@ FMINNUM
FMINNUM/FMAXNUM - Perform floating-point minimum maximum on two values, following IEEE-754 definition...
@ DYNAMIC_STACKALLOC
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary.
@ ANY_EXTEND_VECTOR_INREG
ANY_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register any-extension of the low la...
Definition ISDOpcodes.h:909
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
Definition ISDOpcodes.h:898
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
Definition ISDOpcodes.h:729
@ FP_EXTEND
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
Definition ISDOpcodes.h:988
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
Definition ISDOpcodes.h:815
@ UADDO_CARRY
Carry-using nodes for multiple precision addition and subtraction.
Definition ISDOpcodes.h:328
@ STRICT_SINT_TO_FP
STRICT_[US]INT_TO_FP - Convert a signed or unsigned integer to a floating point value.
Definition ISDOpcodes.h:486
@ STRICT_FROUNDEVEN
Definition ISDOpcodes.h:466
@ FRAMEADDR
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG.
Definition ISDOpcodes.h:110
@ STRICT_FP_TO_UINT
Definition ISDOpcodes.h:480
@ STRICT_FP_ROUND
X = STRICT_FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision ...
Definition ISDOpcodes.h:502
@ STRICT_FP_TO_SINT
STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
Definition ISDOpcodes.h:479
@ FMINIMUM
FMINIMUM/FMAXIMUM - NaN-propagating minimum/maximum that also treat -0.0 as less than 0....
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
Definition ISDOpcodes.h:936
@ READCYCLECOUNTER
READCYCLECOUNTER - This corresponds to the readcyclecounter intrinsic.
@ STRICT_FP_EXTEND
X = STRICT_FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
Definition ISDOpcodes.h:507
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition ISDOpcodes.h:741
@ TRAP
TRAP - Trapping instruction.
@ INTRINSIC_WO_CHAIN
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
Definition ISDOpcodes.h:205
@ STRICT_FADD
Constrained versions of the binary floating point operators.
Definition ISDOpcodes.h:427
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
Definition ISDOpcodes.h:567
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
Definition ISDOpcodes.h:53
@ ATOMIC_SWAP
Val, OUTCHAIN = ATOMIC_SWAP(INCHAIN, ptr, amt) Val, OUTCHAIN = ATOMIC_LOAD_[OpName](INCHAIN,...
@ CTTZ_ZERO_POISON
Bit counting operators with a poisoned result for zero inputs.
Definition ISDOpcodes.h:797
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
Definition ISDOpcodes.h:969
@ ZERO_EXTEND_VECTOR_INREG
ZERO_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register zero-extension of the low ...
Definition ISDOpcodes.h:931
@ ADDRSPACECAST
ADDRSPACECAST - This operator converts between pointers of different address spaces.
@ STRICT_FNEARBYINT
Definition ISDOpcodes.h:458
@ EH_SJLJ_SETJMP
RESULT, OUTCHAIN = EH_SJLJ_SETJMP(INCHAIN, buffer) This corresponds to the eh.sjlj....
Definition ISDOpcodes.h:162
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
Definition ISDOpcodes.h:866
@ BRCOND
BRCOND - Conditional branch.
@ SHL_PARTS
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations.
Definition ISDOpcodes.h:843
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
Definition ISDOpcodes.h:62
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
Definition ISDOpcodes.h:536
@ GET_DYNAMIC_AREA_OFFSET
GET_DYNAMIC_AREA_OFFSET - get offset from native SP to the address of the most recent dynamic alloca.
@ FMINIMUMNUM
FMINIMUMNUM/FMAXIMUMNUM - minimumnum/maximumnum that is same with FMINNUM_IEEE and FMAXNUM_IEEE besid...
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
Definition ISDOpcodes.h:213
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
Definition ISDOpcodes.h:558
bool isNormalStore(const SDNode *N)
Returns true if the specified node is a non-truncating and unindexed store.
LLVM_ABI bool isConstantSplatVectorAllZeros(const SDNode *N, bool BuildVectorOnly=false)
Return true if the specified node is a BUILD_VECTOR or SPLAT_VECTOR where all of the elements are 0 o...
LLVM_ABI CondCode getSetCCInverse(CondCode Operation, EVT Type)
Return the operation corresponding to !(X op Y), where 'op' is a valid SetCC operation.
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.
LLVM_ABI bool isConstantSplatVector(const SDNode *N, APInt &SplatValue)
Node predicates.
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).
bool isNormalLoad(const SDNode *N)
Returns true if the specified node is a non-extending and unindexed load.
Flag
These should be considered private to the implementation of the MCInstrDesc class.
BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)
auto m_Cmp()
Matches any compare instruction and ignore it.
ap_match< APInt > m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
bool match(Val *V, const Pattern &P)
auto m_Value()
Match an arbitrary value and ignore it.
LLVM_ABI Libcall getSINTTOFP(EVT OpVT, EVT RetVT)
getSINTTOFP - Return the SINTTOFP_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getUINTTOFP(EVT OpVT, EVT RetVT)
getUINTTOFP - Return the UINTTOFP_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getFPTOSINT(EVT OpVT, EVT RetVT)
getFPTOSINT - Return the FPTOSINT_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
@ System
Synchronized with respect to all concurrently executing threads.
Definition LLVMContext.h:58
const unsigned GR64Regs[16]
const unsigned VR128Regs[32]
const unsigned VR16Regs[32]
const unsigned GR128Regs[16]
const unsigned FP32Regs[16]
const unsigned FP16Regs[16]
const unsigned GR32Regs[16]
const unsigned FP64Regs[16]
const int64_t ELFCallFrameSize
const unsigned VR64Regs[32]
const unsigned FP128Regs[16]
const unsigned VR32Regs[32]
unsigned odd128(bool Is32bit)
const unsigned CCMASK_CMP_GE
Definition SystemZ.h:41
static bool isImmHH(uint64_t Val)
Definition SystemZ.h:177
const unsigned CCMASK_TEND
Definition SystemZ.h:98
const unsigned CCMASK_CS_EQ
Definition SystemZ.h:68
const unsigned CCMASK_TBEGIN
Definition SystemZ.h:93
const unsigned CCMASK_0
Definition SystemZ.h:28
const MCPhysReg ELFArgFPRs[ELFNumArgFPRs]
MachineBasicBlock * splitBlockBefore(MachineBasicBlock::iterator MI, MachineBasicBlock *MBB)
const unsigned CCMASK_TM_SOME_1
Definition SystemZ.h:83
const unsigned CCMASK_LOGICAL_CARRY
Definition SystemZ.h:61
const unsigned TDCMASK_NORMAL_MINUS
Definition SystemZ.h:123
const unsigned CCMASK_TDC
Definition SystemZ.h:110
const unsigned CCMASK_FCMP
Definition SystemZ.h:49
const unsigned CCMASK_TM_SOME_0
Definition SystemZ.h:82
static bool isImmHL(uint64_t Val)
Definition SystemZ.h:172
const unsigned TDCMASK_SUBNORMAL_MINUS
Definition SystemZ.h:125
const unsigned PFD_READ
Definition SystemZ.h:116
const unsigned CCMASK_1
Definition SystemZ.h:29
const unsigned TDCMASK_NORMAL_PLUS
Definition SystemZ.h:122
const unsigned PFD_WRITE
Definition SystemZ.h:117
const unsigned CCMASK_CMP_GT
Definition SystemZ.h:38
const unsigned TDCMASK_QNAN_MINUS
Definition SystemZ.h:129
const unsigned CCMASK_CS
Definition SystemZ.h:70
const unsigned CCMASK_ANY
Definition SystemZ.h:32
const unsigned CCMASK_ARITH
Definition SystemZ.h:56
const unsigned CCMASK_TM_MIXED_MSB_0
Definition SystemZ.h:79
const unsigned TDCMASK_SUBNORMAL_PLUS
Definition SystemZ.h:124
static bool isImmLL(uint64_t Val)
Definition SystemZ.h:162
const unsigned VectorBits
Definition SystemZ.h:155
static bool isImmLH(uint64_t Val)
Definition SystemZ.h:167
MachineBasicBlock * emitBlockAfter(MachineBasicBlock *MBB)
const unsigned TDCMASK_INFINITY_PLUS
Definition SystemZ.h:126
unsigned reverseCCMask(unsigned CCMask)
const unsigned CCMASK_TM_ALL_0
Definition SystemZ.h:78
const unsigned IPM_CC
Definition SystemZ.h:113
const unsigned CCMASK_CMP_LE
Definition SystemZ.h:40
const unsigned CCMASK_CMP_O
Definition SystemZ.h:45
const unsigned CCMASK_CMP_EQ
Definition SystemZ.h:36
const unsigned VectorBytes
Definition SystemZ.h:159
const unsigned TDCMASK_INFINITY_MINUS
Definition SystemZ.h:127
const unsigned CCMASK_ICMP
Definition SystemZ.h:48
const unsigned CCMASK_VCMP_ALL
Definition SystemZ.h:102
const unsigned CCMASK_VCMP_NONE
Definition SystemZ.h:104
MachineBasicBlock * splitBlockAfter(MachineBasicBlock::iterator MI, MachineBasicBlock *MBB)
const unsigned CCMASK_VCMP
Definition SystemZ.h:105
const unsigned CCMASK_TM_MIXED_MSB_1
Definition SystemZ.h:80
const unsigned CCMASK_TM_MSB_0
Definition SystemZ.h:84
const unsigned CCMASK_ARITH_OVERFLOW
Definition SystemZ.h:55
const unsigned CCMASK_CS_NE
Definition SystemZ.h:69
const unsigned TDCMASK_SNAN_PLUS
Definition SystemZ.h:130
const unsigned CCMASK_TM
Definition SystemZ.h:86
const unsigned CCMASK_3
Definition SystemZ.h:31
const unsigned CCMASK_NONE
Definition SystemZ.h:27
const unsigned CCMASK_CMP_LT
Definition SystemZ.h:37
const unsigned CCMASK_CMP_NE
Definition SystemZ.h:39
const unsigned TDCMASK_ZERO_PLUS
Definition SystemZ.h:120
const unsigned TDCMASK_QNAN_PLUS
Definition SystemZ.h:128
const unsigned TDCMASK_ZERO_MINUS
Definition SystemZ.h:121
unsigned even128(bool Is32bit)
const unsigned CCMASK_TM_ALL_1
Definition SystemZ.h:81
const unsigned CCMASK_LOGICAL_BORROW
Definition SystemZ.h:63
const unsigned ELFNumArgFPRs
const unsigned CCMASK_CMP_UO
Definition SystemZ.h:44
const unsigned CCMASK_LOGICAL
Definition SystemZ.h:65
const unsigned CCMASK_TM_MSB_1
Definition SystemZ.h:85
const unsigned TDCMASK_SNAN_MINUS
Definition SystemZ.h:131
initializer< Ty > init(const Ty &Val)
support::ulittle32_t Word
Definition IRSymtab.h:53
@ User
could "use" a pointer
NodeAddr< UseNode * > Use
Definition RDFGraph.h:385
NodeAddr< NodeBase * > Node
Definition RDFGraph.h:381
NodeAddr< CodeNode * > Code
Definition RDFGraph.h:388
This is an optimization pass for GlobalISel generic memory operations.
@ Low
Lower the current thread's priority such that it does not affect foreground tasks significantly.
Definition Threading.h:280
unsigned Log2_32_Ceil(uint32_t Value)
Return the ceil log base 2 of the specified value, 32 if the value is zero.
Definition MathExtras.h:339
@ Offset
Definition DWP.cpp:578
@ Length
Definition DWP.cpp:578
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
Definition MathExtras.h:166
LLVM_ABI bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
@ Known
Known to have no common set bits.
@ Define
Register definition.
LLVM_ABI SDValue peekThroughBitcasts(SDValue V)
Return the non-bitcasted source operand of V if it exists.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
@ Done
Definition Threading.h:60
@ Load
The value being inserted comes from a load (InsertElement only).
testing::Matcher< const detail::ErrorHolder & > Failed()
Definition Error.h:198
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
constexpr T maskLeadingOnes(unsigned N)
Create a bitmask with the N left-most bits set to 1, and all other bits set to 0.
Definition MathExtras.h:89
constexpr bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
Definition MathExtras.h:244
LLVM_ABI void dumpBytes(ArrayRef< uint8_t > Bytes, raw_ostream &OS)
Convert ‘Bytes’ to a hex string and output to ‘OS’.
T bit_ceil(T Value)
Returns the smallest integral power of two no smaller than Value if Value is nonzero.
Definition bit.h:362
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
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.
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition MathExtras.h:280
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
Definition MathExtras.h:190
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
@ Success
The lock was released successfully.
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
AtomicOrdering
Atomic ordering for LLVM's memory model.
constexpr T divideCeil(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
Definition MathExtras.h:389
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
Definition ModRef.h:74
@ BeforeLegalizeTypes
Definition DAGCombine.h:16
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 unsigned BitWidth
ExceptionHandling
Definition CodeGen.h:54
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
UndefPoisonKind
Enumeration to track whether we are interested in Undef, Poison, or both.
Definition UndefPoison.h:20
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
Definition MathExtras.h:567
constexpr T maskTrailingOnes(unsigned N)
Create a bitmask with the N right-most bits set to 1, and all other bits set to 0.
Definition MathExtras.h:78
T bit_floor(T Value)
Returns the largest integral power of two no greater than Value if Value is nonzero.
Definition bit.h:347
LLVM_ABI bool isAllOnesConstant(SDValue V)
Returns true if V is an integer constant with all bits set.
MCRegisterClass TargetRegisterClass
Definition FastISel.h:58
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:880
#define N
#define EQ(a, b)
Definition regexec.c:65
AddressingMode(bool LongDispl, bool IdxReg)
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
Extended Value Type.
Definition ValueTypes.h:35
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
Definition ValueTypes.h:90
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
Definition ValueTypes.h:418
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
Definition ValueTypes.h:145
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT.
Definition ValueTypes.h:70
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
Definition ValueTypes.h:155
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
Definition ValueTypes.h:396
uint64_t getScalarSizeInBits() const
Definition ValueTypes.h:408
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition ValueTypes.h:339
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 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.
bool isRound() const
Return true if the size is a power-of-two number of bytes.
Definition ValueTypes.h:271
EVT getVectorElementType() const
Given a vector type, return the type of each element.
Definition ValueTypes.h:351
bool isVectorOf(EVT EltVT) const
Return true if this is a vector with matching element type.
Definition ValueTypes.h:181
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 isInteger() const
Return true if this is an integer or a vector integer type.
Definition ValueTypes.h:160
KnownBits intersectWith(const KnownBits &RHS) const
Returns KnownBits information that is known to be true for both this and RHS.
Definition KnownBits.h:325
APInt getMaxValue() const
Return the maximal unsigned value possible given these KnownBits.
Definition KnownBits.h:146
This class contains a discriminated union of information about pointers in memory operands,...
static LLVM_ABI MachinePointerInfo getConstantPool(MachineFunction &MF)
Return a MachinePointerInfo record that refers to the constant pool.
MachinePointerInfo getWithOffset(int64_t O) const
static LLVM_ABI MachinePointerInfo getGOT(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a GOT entry.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
SmallVector< unsigned, 2 > OpVals
bool isVectorConstantLegal(const SystemZSubtarget &Subtarget)
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.
SmallVector< ISD::InputArg, 32 > Ins
CallLoweringInfo & setDiscardResult(bool Value=true)
CallLoweringInfo & setZExtResult(bool Value=true)
CallLoweringInfo & setDebugLoc(const SDLoc &dl)
CallLoweringInfo & setSExtResult(bool Value=true)
CallLoweringInfo & setNoReturn(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={})
This structure is used to pass arguments to makeLibCall function.