LLVM: lib/Target/AMDGPU/AMDGPUISelLowering.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
25#include "llvm/IR/IntrinsicsAMDGPU.h"
29
30using namespace llvm;
31
32#include "AMDGPUGenCallingConv.inc"
33
35 "amdgpu-bypass-slow-div",
36 cl::desc("Skip 64-bit divide for dynamic 32-bit values"),
38
39
42 if (StoreSize <= 32)
44
45 if (StoreSize % 32 == 0)
47
48 return VT;
49}
50
53}
54
56
57
59}
60
64
65
69
70
72
73
74
77
80
83
86
89
92
95
98
101
104
107
110
113
116
119
122
125
128
131
134
137
140
143
146
149
152
155
156
159
162
165
168
171
174
177
180
181
182
186
188 if (VT == MVT::i64)
189 continue;
190
196 }
197 }
198
200 for (auto MemVT :
201 {MVT::v2i8, MVT::v4i8, MVT::v2i16, MVT::v3i16, MVT::v4i16})
204
219
226
239
242
245
248
251
254
257
260
263
266
269
272
275
278
281
284
287
290
293
296
299
302
305
308
311
314
317
320
325
330
345
349
353
355
363
369
373
382
385
387
388
389
391
392
393
396 MVT::f32, Legal);
397
401 {MVT::f16, MVT::f32, MVT::f64}, Expand);
402
406
408
410
413
415
418 else {
421 }
422
425
426
427
428
430 {MVT::v2f32, MVT::v3f32, MVT::v4f32, MVT::v5f32,
431 MVT::v6f32, MVT::v7f32, MVT::v8f32, MVT::v16f32,
432 MVT::v2f64, MVT::v3f64, MVT::v4f64, MVT::v8f64,
433 MVT::v16f64},
435
438 {MVT::v2f16, MVT::v3f16, MVT::v4f16, MVT::v16f16},
440
441
443
445 {MVT::v3i32, MVT::v3f32, MVT::v4i32, MVT::v4f32,
446 MVT::v5i32, MVT::v5f32, MVT::v6i32, MVT::v6f32,
447 MVT::v7i32, MVT::v7f32, MVT::v8i32, MVT::v8f32,
448 MVT::v9i32, MVT::v9f32, MVT::v10i32, MVT::v10f32,
449 MVT::v11i32, MVT::v11f32, MVT::v12i32, MVT::v12f32},
451
454 {MVT::v2f32, MVT::v2i32, MVT::v3f32, MVT::v3i32, MVT::v4f32,
455 MVT::v4i32, MVT::v5f32, MVT::v5i32, MVT::v6f32, MVT::v6i32,
456 MVT::v7f32, MVT::v7i32, MVT::v8f32, MVT::v8i32, MVT::v9f32,
457 MVT::v9i32, MVT::v10i32, MVT::v10f32, MVT::v11i32, MVT::v11f32,
458 MVT::v12i32, MVT::v12f32, MVT::v16i32, MVT::v32f32, MVT::v32i32,
459 MVT::v2f64, MVT::v2i64, MVT::v3f64, MVT::v3i64, MVT::v4f64,
460 MVT::v4i64, MVT::v8f64, MVT::v8i64, MVT::v16f64, MVT::v16i64},
462
465
466 const MVT ScalarIntVTs[] = { MVT::i32, MVT::i64 };
467 for (MVT VT : ScalarIntVTs) {
468
471
472
474
475
477
479
480
482 }
483
484
486
487
490
492
498
501
505
506 for (auto VT : {MVT::i8, MVT::i16})
508
510 MVT::v2i32, MVT::v3i32, MVT::v4i32, MVT::v5i32, MVT::v6i32, MVT::v7i32,
511 MVT::v9i32, MVT::v10i32, MVT::v11i32, MVT::v12i32};
512
513 for (MVT VT : VectorIntTypes) {
514
528 }
529
531 MVT::v2f32, MVT::v3f32, MVT::v4f32, MVT::v5f32, MVT::v6f32, MVT::v7f32,
532 MVT::v9f32, MVT::v10f32, MVT::v11f32, MVT::v12f32};
533
534 for (MVT VT : FloatVectorTypes) {
548 }
549
550
551
552
555
558
561
564
567
570
573
576
579
582
585
586
587
588
589
590
591
593
596
598
599
600
601
602
603
604
605
606
608
609
610
614
615
618
629
633}
634
637 return true;
638
639 const auto Flags = Op.getNode()->getFlags();
640 if (Flags.hasNoSignedZeros())
641 return true;
642
643 return false;
644}
645
646
647
648
649
652 switch (Opc) {
679
680 return true;
683 default:
684 return false;
685 }
686}
687
689 unsigned Opc = N->getOpcode();
691
692
693 SDValue BCSrc = N->getOperand(0);
697 }
698
700 }
701
703}
704
705
706
707
710 return (N->getNumOperands() > 2 && N->getOpcode() != ISD::SELECT) ||
711 VT == MVT::f64;
712}
713
714
715
718
719 return N->getValueType(0) == MVT::f32;
720}
721
722
723
726 if (isa(N))
727 return false;
728
729 switch (N->getOpcode()) {
737
738
739
740
742 return false;
744 switch (N->getConstantOperandVal(0)) {
745 case Intrinsic::amdgcn_interp_p1:
746 case Intrinsic::amdgcn_interp_p2:
747 case Intrinsic::amdgcn_interp_mov:
748 case Intrinsic::amdgcn_interp_p1_f16:
749 case Intrinsic::amdgcn_interp_p2_f16:
750 return false;
751 default:
752 return true;
753 }
754 }
757 default:
758 return true;
759 }
760}
761
764
765
766
767
768
769 unsigned NumMayIncreaseSize = 0;
770 MVT VT = N->getValueType(0).getScalarType().getSimpleVT();
771
773
774
775 for (const SDNode *U : N->users()) {
777 return false;
778
781 return false;
782 }
783 }
784
785 return true;
786}
787
791
792
794 if (Size <= 32)
795 return MVT::i32;
797}
798
800 return MVT::i32;
801}
802
804 return true;
805}
806
807
808
810 bool ForCodeSize) const {
812 return (ScalarVT == MVT::f32 || ScalarVT == MVT::f64 ||
813 (ScalarVT == MVT::f16 && Subtarget->has16BitInsts()));
814}
815
816
819 return (ScalarVT != MVT::f32 && ScalarVT != MVT::f64);
820}
821
824 EVT NewVT) const {
825
827 return false;
828
830
831
832
833 if (NewSize >= 32)
834 return true;
835
836 EVT OldVT = N->getValueType(0);
838
841
842
843
844 if (OldSize >= 32 && NewSize < 32 && MN->getAlign() >= Align(4) &&
850 return false;
851
852
853
854
855
856
857
858
859 return (OldSize < 32);
860}
861
865
867
869 return false;
870
873
874 if ((LScalarSize >= CastScalarSize) && (CastScalarSize < 32))
875 return false;
876
877 unsigned Fast = 0;
879 CastTy, MMO, &Fast) &&
881}
882
883
884
885
887 return true;
888}
889
891 return true;
892}
893
895 switch (N->getOpcode()) {
898 return true;
900 unsigned IntrID = N->getConstantOperandVal(0);
902 }
904 unsigned IntrID = N->getConstantOperandVal(1);
906 }
908 if (cast(N)->getMemOperand()->getAddrSpace() ==
910 return true;
911 return false;
913 return true;
914 }
915 return false;
916}
917
921
922 switch (Op.getOpcode()) {
925
928 break;
929 }
932 EVT VT = Op.getValueType();
934
937 if (NegSrc)
940 }
941 default:
942 break;
943 }
944
947}
948
949
950
951
952
955
956
957 return VT == MVT::f32 || VT == MVT::f64 ||
958 (Subtarget->has16BitInsts() && (VT == MVT::f16 || VT == MVT::bf16));
959}
960
963
965 return VT == MVT::f32 || VT == MVT::f64 || VT == MVT::f16 || VT == MVT::bf16;
966}
967
969 unsigned NumElem,
970 unsigned AS) const {
971 return true;
972}
973
975
976
977
978
979
980
981
982
983 return true;
984}
985
987
988
989 unsigned SrcSize = Source.getSizeInBits();
991
992 return DestSize < SrcSize && DestSize % 32 == 0 ;
993}
994
996
997
998 unsigned SrcSize = Source->getScalarSizeInBits();
1000
1001 if (DestSize== 16 && Subtarget->has16BitInsts())
1002 return SrcSize >= 32;
1003
1004 return DestSize < SrcSize && DestSize % 32 == 0;
1005}
1006
1008 unsigned SrcSize = Src->getScalarSizeInBits();
1010
1011 if (SrcSize == 16 && Subtarget->has16BitInsts())
1012 return DestSize >= 32;
1013
1014 return SrcSize == 32 && DestSize == 64;
1015}
1016
1018
1019
1020
1021
1022
1023 if (Src == MVT::i16)
1024 return Dest == MVT::i32 ||Dest == MVT::i64 ;
1025
1026 return Src == MVT::i32 && Dest == MVT::i64;
1027}
1028
1030 EVT DestVT) const {
1031 switch (N->getOpcode()) {
1045
1046 if (->isDivergent() && DestVT.isInteger() &&
1050 return false;
1051 }
1052 }
1053 return true;
1054 default:
1055 break;
1056 }
1057
1058
1059
1060
1061
1062
1063
1064 if (isa(N))
1066
1067 return true;
1068}
1069
1074 "Expected shift op");
1075
1076 SDValue ShiftLHS = N->getOperand(0);
1078 return false;
1079
1082 return false;
1083
1084
1085
1087 N->getOpcode() != ISD::SHL || N->getOperand(0).getOpcode() != ISD::OR)
1088 return true;
1089
1090
1091 if (N->getValueType(0) == MVT::i32 && N->hasOneUse() &&
1092 (N->user_begin()->getOpcode() == ISD::SRA ||
1093 N->user_begin()->getOpcode() == ISD::SRL))
1094 return false;
1095
1096
1099 return false;
1100 auto *RHSLd = dyn_cast(RHS);
1101 auto *LHS0 = dyn_cast(LHS.getOperand(0));
1102 auto *LHS1 = dyn_cast(LHS.getOperand(1));
1103 return LHS0 && LHS1 && RHSLd && LHS0->getExtensionType() == ISD::ZEXTLOAD &&
1104 LHS1->getAPIntValue() == LHS0->getMemoryVT().getScalarSizeInBits() &&
1106 };
1107 SDValue LHS = N->getOperand(0).getOperand(0);
1108 SDValue RHS = N->getOperand(0).getOperand(1);
1109 return !(IsShiftAndLoad(LHS, RHS) || IsShiftAndLoad(RHS, LHS));
1110}
1111
1112
1113
1114
1115
1117 bool IsVarArg) {
1118 switch (CC) {
1126 return CC_AMDGPU;
1129 return CC_AMDGPU_CS_CHAIN;
1133 return CC_AMDGPU_Func;
1135 return CC_SI_Gfx;
1138 default:
1140 }
1141}
1142
1144 bool IsVarArg) {
1145 switch (CC) {
1158 return RetCC_SI_Shader;
1160 return RetCC_SI_Gfx;
1164 return RetCC_AMDGPU_Func;
1165 default:
1167 }
1168}
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1203 const unsigned ExplicitOffset = ST.getExplicitKernelArgOffset();
1205
1207 uint64_t ExplicitArgOffset = 0;
1209
1210 unsigned InIndex = 0;
1211
1213 const bool IsByRef = Arg.hasByRefAttr();
1214 Type *BaseArgTy = Arg.getType();
1215 Type *MemArgTy = IsByRef ? Arg.getParamByRefType() : BaseArgTy;
1216 Align Alignment = DL.getValueOrABITypeAlignment(
1217 IsByRef ? Arg.getParamAlign() : std::nullopt, MemArgTy);
1218 MaxAlign = std::max(Alignment, MaxAlign);
1219 uint64_t AllocSize = DL.getTypeAllocSize(MemArgTy);
1220
1221 uint64_t ArgOffset = alignTo(ExplicitArgOffset, Alignment) + ExplicitOffset;
1222 ExplicitArgOffset = alignTo(ExplicitArgOffset, Alignment) + AllocSize;
1223
1224
1225
1226
1227
1228
1229
1230
1233 ComputeValueVTs(*this, DL, BaseArgTy, ValueVTs, &Offsets, ArgOffset);
1234
1235 for (unsigned Value = 0, NumValues = ValueVTs.size();
1238
1239 EVT ArgVT = ValueVTs[Value];
1240 EVT MemVT = ArgVT;
1243
1244 if (NumRegs == 1) {
1245
1247
1248
1249 MemVT = RegisterVT;
1250 } else {
1251 MemVT = ArgVT;
1252 }
1256
1257
1258
1259 MemVT = RegisterVT;
1260 } else if (ArgVT.isVector() &&
1262
1263
1266
1267 MemVT = RegisterVT;
1268 } else {
1273 } else if (RegisterVT.isVector()) {
1276 assert(MemoryBits % NumElements == 0);
1277
1278
1280 MemoryBits / NumElements);
1282 } else {
1284 }
1285 }
1286
1287
1290
1291
1296 }
1297
1298 unsigned PartOffset = 0;
1299 for (unsigned i = 0; i != NumRegs; ++i) {
1301 BasePartOffset + PartOffset,
1305 }
1306 }
1307 }
1308}
1309
1312 bool isVarArg,
1316
1317
1318
1320}
1321
1322
1323
1324
1325
1326
1328 bool IsVarArg) {
1330}
1331
1333 bool IsVarArg) {
1335}
1336
1340 int ClobberedFI) const {
1343 int64_t LastByte = FirstByte + MFI.getObjectSize(ClobberedFI) - 1;
1344
1345
1346
1347
1349
1350
1352 if (LoadSDNode *L = dyn_cast(U)) {
1353 if (FrameIndexSDNode *FI = dyn_cast(L->getBasePtr())) {
1354 if (FI->getIndex() < 0) {
1355 int64_t InFirstByte = MFI.getObjectOffset(FI->getIndex());
1356 int64_t InLastByte = InFirstByte;
1357 InLastByte += MFI.getObjectSize(FI->getIndex()) - 1;
1358
1359 if ((InFirstByte <= FirstByte && FirstByte <= InLastByte) ||
1360 (FirstByte <= InFirstByte && InFirstByte <= LastByte))
1362 }
1363 }
1364 }
1365 }
1366
1367
1369}
1370
1376
1378
1379 StringRef FuncName("");
1380
1382 FuncName = G->getSymbol();
1383 else if (const GlobalAddressSDNode *G = dyn_cast(Callee))
1384 FuncName = G->getGlobal()->getName();
1385
1389
1393 }
1394
1396}
1397
1400 return lowerUnhandledCall(CLI, InVals, "unsupported call to function ");
1401}
1402
1406
1410 auto Ops = {DAG.getConstant(0, SDLoc(), Op.getValueType()), Op.getOperand(0)};
1412}
1413
1416 switch (Op.getOpcode()) {
1417 default:
1420 "instruction is not implemented yet!");
1421 break;
1458 }
1459 return Op;
1460}
1461
1465 switch (N->getOpcode()) {
1467
1468
1469
1470
1471
1472
1473 return;
1476 Results.push_back(Lowered);
1477 return;
1481 Results.push_back(Lowered);
1482 return;
1485 Results.push_back(Lowered);
1486 return;
1490 Results.push_back(Lowered);
1491 return;
1495 Results.push_back(Lowered);
1496 return;
1497 default:
1498 return;
1499 }
1500}
1501
1505
1509
1511 if (std::optional<uint32_t> Address =
1514 }
1515 }
1516
1520 GV->getName() != "llvm.amdgcn.module.lds" &&
1525 Fn, "local memory global used by non-kernel function",
1528
1529
1530
1531
1532
1533
1537 DAG.setRoot(OutputChain);
1538 return DAG.getUNDEF(Op.getValueType());
1539 }
1540
1541
1542 assert(G->getOffset() == 0 &&
1543 "Do not know what to do with an non-zero offset");
1544
1545
1546
1547
1550 }
1552}
1553
1558
1559 EVT VT = Op.getValueType();
1561 unsigned OpBitSize = Op.getOperand(0).getValueType().getSizeInBits();
1562 if (OpBitSize >= 32 && OpBitSize % 32 == 0) {
1563 unsigned NewNumElt = OpBitSize / 32;
1564 EVT NewEltVT = (NewNumElt == 1) ? MVT::i32
1566 MVT::i32, NewNumElt);
1567 for (const SDUse &U : Op->ops()) {
1570 if (NewNumElt > 1)
1572 else
1573 Args.push_back(NewIn);
1574 }
1575
1580 }
1581 }
1582
1583 for (const SDUse &U : Op->ops())
1585
1587}
1588
1593 unsigned Start = Op.getConstantOperandVal(1);
1594 EVT VT = Op.getValueType();
1595 EVT SrcVT = Op.getOperand(0).getValueType();
1596
1600 assert(NumElt % 2 == 0 && NumSrcElt % 2 == 0 && "expect legal types");
1601
1602
1604 EVT NewVT = NumElt == 2
1605 ? MVT::i32
1608
1610 if (NumElt == 2)
1611 Tmp = Args[0];
1612 else
1614
1616 }
1617
1620
1622}
1623
1624
1628
1629 return Val;
1630}
1631
1639 return Val;
1640}
1641
1646 ISD::CondCode CCOpcode = cast(CC)->get();
1647 switch (CCOpcode) {
1660 break;
1663 if (LHS == True)
1666 }
1671
1672
1673
1674
1678
1679
1680
1681
1682 if (LHS == True)
1685 }
1688 if (LHS == True)
1691 }
1699
1700 if (LHS == True)
1703 }
1706 }
1708}
1709
1710
1716 if ((LHS == True && RHS == False) || (LHS == False && RHS == True))
1718
1720
1721
1722
1723
1725 ConstantFPSDNode *CFalse = dyn_cast(False);
1727
1728
1729
1730
1731
1732
1733
1734
1735 if (LHS == NegTrue && CFalse && CRHS) {
1740 if (Combined)
1743 }
1744 }
1745
1747}
1748
1749std::pair<SDValue, SDValue>
1752
1754
1757
1760
1761 return std::pair(Lo, Hi);
1762}
1763
1766
1770}
1771
1774
1778}
1779
1780
1781
1782
1783std::pair<EVT, EVT>
1785 EVT LoVT, HiVT;
1788 unsigned LoNumElts = PowerOf2Ceil((NumElts + 1) / 2);
1790 HiVT = NumElts - LoNumElts == 1
1791 ? EltVT
1793 return std::pair(LoVT, HiVT);
1794}
1795
1796
1797
1798std::pair<SDValue, SDValue>
1800 const EVT &LoVT, const EVT &HiVT,
1804 N.getValueType().getVectorNumElements() &&
1805 "More vector elements requested than available!");
1811 return std::pair(Lo, Hi);
1812}
1813
1817 EVT VT = Op.getValueType();
1819
1820
1821
1822
1827 }
1828
1829 SDValue BasePtr = Load->getBasePtr();
1830 EVT MemVT = Load->getMemoryVT();
1831
1832 const MachinePointerInfo &SrcValue = Load->getMemOperand()->getPointerInfo();
1833
1834 EVT LoVT, HiVT;
1835 EVT LoMemVT, HiMemVT;
1837
1839 std::tie(LoMemVT, HiMemVT) = getSplitDestVTs(MemVT, DAG);
1841
1843 Align BaseAlign = Load->getAlign();
1845
1846 SDValue LoLoad = DAG.getExtLoad(Load->getExtensionType(), SL, LoVT,
1847 Load->getChain(), BasePtr, SrcValue, LoMemVT,
1848 BaseAlign, Load->getMemOperand()->getFlags());
1851 DAG.getExtLoad(Load->getExtensionType(), SL, HiVT, Load->getChain(),
1853 HiMemVT, HiAlign, Load->getMemOperand()->getFlags());
1854
1856 if (LoVT == HiVT) {
1857
1859 } else {
1864 VT, Join, HiLoad,
1866 }
1867
1870
1872}
1873
1877 EVT VT = Op.getValueType();
1878 SDValue BasePtr = Load->getBasePtr();
1879 EVT MemVT = Load->getMemoryVT();
1881 const MachinePointerInfo &SrcValue = Load->getMemOperand()->getPointerInfo();
1882 Align BaseAlign = Load->getAlign();
1884
1885
1886
1887 if (NumElements != 3 ||
1888 (BaseAlign < Align(8) &&
1891
1892 assert(NumElements == 3);
1893
1894 EVT WideVT =
1896 EVT WideMemVT =
1899 Load->getExtensionType(), SL, WideVT, Load->getChain(), BasePtr, SrcValue,
1900 WideMemVT, BaseAlign, Load->getMemOperand()->getFlags());
1905 SL);
1906}
1907
1911 SDValue Val = Store->getValue();
1913
1914
1915
1918
1919 EVT MemVT = Store->getMemoryVT();
1920 SDValue Chain = Store->getChain();
1921 SDValue BasePtr = Store->getBasePtr();
1923
1924 EVT LoVT, HiVT;
1925 EVT LoMemVT, HiMemVT;
1927
1929 std::tie(LoMemVT, HiMemVT) = getSplitDestVTs(MemVT, DAG);
1930 std::tie(Lo, Hi) = splitVector(Val, SL, LoVT, HiVT, DAG);
1931
1933
1934 const MachinePointerInfo &SrcValue = Store->getMemOperand()->getPointerInfo();
1935 Align BaseAlign = Store->getAlign();
1938
1940 DAG.getTruncStore(Chain, SL, Lo, BasePtr, SrcValue, LoMemVT, BaseAlign,
1941 Store->getMemOperand()->getFlags());
1944 HiMemVT, HiAlign, Store->getMemOperand()->getFlags());
1945
1947}
1948
1949
1950
1951
1953 bool Sign) const {
1955 EVT VT = Op.getValueType();
1958 MVT IntVT = MVT::i32;
1959 MVT FltVT = MVT::f32;
1960
1962 if (LHSSignBits < 9)
1964
1966 if (RHSSignBits < 9)
1968
1970 unsigned SignBits = std::min(LHSSignBits, RHSSignBits);
1971 unsigned DivBits = BitSize - SignBits;
1972 if (Sign)
1973 ++DivBits;
1974
1977
1979
1980 if (Sign) {
1981
1983
1984
1987
1988
1990 }
1991
1992
1994
1995
1997
1998
2000
2001
2003
2006
2007
2009
2010
2012
2014
2015 bool UseFmadFtz = false;
2016 if (Subtarget->isGCN()) {
2018 UseFmadFtz =
2020 }
2021
2022
2027
2028
2030
2031
2033
2034
2036
2038
2039
2041
2042
2044
2045
2047
2048
2051
2052
2053 if (Sign) {
2058 } else {
2062 }
2063
2065}
2066
2071 EVT VT = Op.getValueType();
2072
2073 assert(VT == MVT::i64 && "LowerUDIVREM64 expects an i64");
2074
2076
2079
2080
2083 std::tie(LHS_Lo, LHS_Hi) = DAG.SplitScalar(LHS, DL, HalfVT, HalfVT);
2084
2087 std::tie(RHS_Lo, RHS_Hi) = DAG.SplitScalar(RHS, DL, HalfVT, HalfVT);
2088
2091
2093 LHS_Lo, RHS_Lo);
2094
2097
2100 return;
2101 }
2102
2104
2105
2106
2109
2110
2111 unsigned FMAD =
2116
2121 Cvt_Lo);
2130 Mul1);
2135
2140
2141
2145 SDValue Mulhi1_Lo, Mulhi1_Hi;
2146 std::tie(Mulhi1_Lo, Mulhi1_Hi) =
2149 Mulhi1_Lo, Zero1);
2151 Mulhi1_Hi, Add1_Lo.getValue(1));
2154
2155
2158 SDValue Mulhi2_Lo, Mulhi2_Hi;
2159 std::tie(Mulhi2_Lo, Mulhi2_Hi) =
2162 Mulhi2_Lo, Zero1);
2164 Mulhi2_Hi, Add2_Lo.getValue(1));
2167
2169
2171
2172 SDValue Mul3_Lo, Mul3_Hi;
2173 std::tie(Mul3_Lo, Mul3_Hi) = DAG.SplitScalar(Mul3, DL, HalfVT, HalfVT);
2175 Mul3_Lo, Zero1);
2177 Mul3_Hi, Sub1_Lo.getValue(1));
2181
2188
2189
2190
2191
2192
2193
2195 RHS_Lo, Zero1);
2197 RHS_Hi, Sub1_Lo.getValue(1));
2202
2204
2210
2211
2213
2215 RHS_Lo, Zero1);
2217 RHS_Hi, Sub2_Lo.getValue(1));
2222
2223
2224
2225
2228
2231
2234
2235 return;
2236 }
2237
2238
2239
2242
2246
2249
2250 const unsigned halfBitWidth = HalfVT.getSizeInBits();
2251
2252 for (unsigned i = 0; i < halfBitWidth; ++i) {
2253 const unsigned bitPos = halfBitWidth - i - 1;
2255
2259
2260
2262
2264
2267
2269
2270
2273 }
2274
2279}
2280
2284 EVT VT = Op.getValueType();
2285
2286 if (VT == MVT::i64) {
2290 }
2291
2292 if (VT == MVT::i32) {
2294 return Res;
2295 }
2296
2299
2300
2301
2302
2303
2305
2306
2311
2312
2316
2317
2325
2326
2332
2334}
2335
2339 EVT VT = Op.getValueType();
2340
2343
2346
2347 if (VT == MVT::i32) {
2349 return Res;
2350 }
2351
2352 if (VT == MVT::i64 &&
2356
2357
2361 LHS_Lo, RHS_Lo);
2365 };
2367 }
2368
2372 SDValue RSign = LHSign;
2373
2376
2379
2382
2385
2388
2390 Div,
2391 Rem
2392 };
2394}
2395
2396
2399 EVT VT = Op.getValueType();
2400 auto Flags = Op->getFlags();
2403
2407
2409}
2410
2414
2415
2416
2417
2418
2420
2423
2424 EVT SetCCVT =
2426
2430
2432
2434}
2435
2438 const unsigned FractBits = 52;
2439 const unsigned ExpBits = 11;
2440
2443 DAG.getConstant(FractBits - 32, SL, MVT::i32),
2444 DAG.getConstant(ExpBits, SL, MVT::i32));
2447
2448 return Exp;
2449}
2450
2454
2455 assert(Op.getValueType() == MVT::f64);
2456
2458
2459
2460
2462
2464
2465 const unsigned FractBits = 52;
2466
2467
2468 const SDValue SignBitMask = DAG.getConstant(UINT32_C(1) << 31, SL, MVT::i32);
2470
2471
2474
2477 = DAG.getConstant((UINT64_C(1) << FractBits) - 1, SL, MVT::i64);
2478
2482
2483 EVT SetCCVT =
2485
2486 const SDValue FiftyOne = DAG.getConstant(FractBits - 1, SL, MVT::i32);
2487
2490
2493
2495}
2496
2501
2502 assert(Op.getValueType() == MVT::f64);
2503
2507
2508
2509
2512
2514
2517
2518 EVT SetCCVT =
2521
2522 return DAG.getSelect(SL, MVT::f64, Cond, Src, Tmp2);
2523}
2524
2527
2528
2529
2531 Op.getOperand(0));
2532}
2533
2535 auto VT = Op.getValueType();
2536 auto Arg = Op.getOperand(0u);
2538}
2539
2540
2541
2542
2543
2544
2548 EVT VT = Op.getValueType();
2549
2551
2552
2553
2555
2557
2560
2561 EVT SetCCVT =
2563
2567
2570}
2571
2575
2576
2577
2578
2579
2581
2584
2585 EVT SetCCVT =
2587
2591
2593
2595}
2596
2597
2599 switch (Src.getOpcode()) {
2601 return Src.getOperand(0).getValueType() == MVT::f16;
2604 return true;
2606 unsigned IntrinsicID = Src.getConstantOperandVal(0);
2607 switch (IntrinsicID) {
2608 case Intrinsic::amdgcn_frexp_mant:
2609 return true;
2610 default:
2611 return false;
2612 }
2613 }
2614 default:
2615 return false;
2616 }
2617
2619}
2620
2623 if (Flags.hasApproximateFuncs())
2624 return true;
2626 return Options.UnsafeFPMath || Options.ApproxFuncFPMath;
2627}
2628
2636}
2637
2642 EVT VT = Src.getValueType();
2644 SDValue SmallestNormal =
2646
2647
2648
2652
2653 return IsLtSmallestNormal;
2654}
2655
2659 EVT VT = Src.getValueType();
2662
2667 return IsFinite;
2668}
2669
2670
2671
2672std::pair<SDValue, SDValue>
2676 return {};
2677
2678 MVT VT = MVT::f32;
2680 SDValue SmallestNormal =
2682
2686
2690 DAG.getNode(ISD::SELECT, SL, VT, IsLtSmallestNormal, Scale32, One, Flags);
2691
2693 return {ScaledInput, IsLtSmallestNormal};
2694}
2695
2697
2698
2699
2700
2701
2702
2704 EVT VT = Op.getValueType();
2707
2708 if (VT == MVT::f16) {
2709
2715 }
2716
2717 auto [ScaledInput, IsLtSmallestNormal] =
2719 if (!ScaledInput)
2721
2723
2727 DAG.getNode(ISD::SELECT, SL, VT, IsLtSmallestNormal, ThirtyTwo, Zero);
2729}
2730
2735}
2736
2740 EVT VT = Op.getValueType();
2743
2744 const bool IsLog10 = Op.getOpcode() == ISD::FLOG10;
2746
2748 if (VT == MVT::f16 || Flags.hasApproximateFuncs() ||
2750
2751 if (VT == MVT::f16 && !Subtarget->has16BitInsts()) {
2752
2754 }
2755
2757 if (VT == MVT::f16 && !Subtarget->has16BitInsts()) {
2760 }
2761
2762 return Lowered;
2763 }
2764
2766 if (ScaledInput)
2767 X = ScaledInput;
2768
2770
2773
2774 const float c_log10 = 0x1.344134p-2f;
2775 const float cc_log10 = 0x1.09f79ep-26f;
2776
2777
2778 const float c_log = 0x1.62e42ep-1f;
2779 const float cc_log = 0x1.efa39ep-25f;
2780
2783
2789 } else {
2790
2791 const float ch_log10 = 0x1.344000p-2f;
2792 const float ct_log10 = 0x1.3509f6p-18f;
2793
2794
2795 const float ch_log = 0x1.62e000p-1f;
2796 const float ct_log = 0x1.0bfbe8p-15f;
2797
2800
2806
2808 SDValue Mad0 = getMad(DAG, DL, VT, YH, CT, YTCT, Flags);
2810 R = getMad(DAG, DL, VT, YH, CH, Mad1);
2811 }
2812
2813 const bool IsFiniteOnly = (Flags.hasNoNaNs() || Options.NoNaNsFPMath) &&
2814 (Flags.hasNoInfs() || Options.NoInfsFPMath);
2815
2816
2817 if (!IsFiniteOnly) {
2820 }
2821
2822 if (IsScaled) {
2825 DAG.getConstantFP(IsLog10 ? 0x1.344136p+3f : 0x1.62e430p+4f, DL, VT);
2829 }
2830
2831 return R;
2832}
2833
2836}
2837
2838
2839
2843 EVT VT = Src.getValueType();
2844 unsigned LogOp =
2846
2847 double Log2BaseInverted =
2849
2850 if (VT == MVT::f32) {
2851 auto [ScaledInput, IsScaled] = getScaledLogInput(DAG, SL, Src, Flags);
2852 if (ScaledInput) {
2854 SDValue ScaledResultOffset =
2855 DAG.getConstantFP(-32.0 * Log2BaseInverted, SL, VT);
2856
2858
2860 ScaledResultOffset, Zero, Flags);
2861
2863
2865 return DAG.getNode(ISD::FMA, SL, VT, LogSrc, Log2Inv, ResultOffset,
2866 Flags);
2869 }
2870 }
2871
2872 SDValue Log2Operand = DAG.getNode(LogOp, SL, VT, Src, Flags);
2873 SDValue Log2BaseInvertedOperand = DAG.getConstantFP(Log2BaseInverted, SL, VT);
2874
2875 return DAG.getNode(ISD::FMUL, SL, VT, Log2Operand, Log2BaseInvertedOperand,
2876 Flags);
2877}
2878
2880
2881
2882
2884 EVT VT = Op.getValueType();
2887
2888 if (VT == MVT::f16) {
2889
2895 }
2896
2897 assert(VT == MVT::f32);
2898
2901
2902
2903
2904
2905
2907
2909
2912
2915
2918
2921
2926
2927 return DAG.getNode(ISD::FMUL, SL, VT, Exp2, ResultScale, Flags);
2928}
2929
2933 EVT VT = X.getValueType();
2935
2937
2941 SL, VT, Mul, Flags);
2942 }
2943
2945
2948
2950
2952
2955
2957
2959
2961 SDValue AdjustedResult =
2962 DAG.getNode(ISD::FMUL, SL, VT, Exp2, ResultScaleFactor, Flags);
2963
2964 return DAG.getNode(ISD::SELECT, SL, VT, NeedsScaling, AdjustedResult, Exp2,
2965 Flags);
2966}
2967
2968
2969
2973 const EVT VT = X.getValueType();
2975
2977
2980
2982 SDValue Exp2_0 = DAG.getNode(Exp2Op, SL, VT, Mul0, Flags);
2984 SDValue Exp2_1 = DAG.getNode(Exp2Op, SL, VT, Mul1, Flags);
2986 }
2987
2988
2989
2990
2991
2992
2993
2995
2998
3003
3006
3008 SDValue Exp2_0 = DAG.getNode(Exp2Op, SL, VT, Mul0, Flags);
3010 SDValue Exp2_1 = DAG.getNode(Exp2Op, SL, VT, Mul1, Flags);
3011
3013
3015 SDValue AdjustedResult =
3016 DAG.getNode(ISD::FMUL, SL, VT, MulExps, ResultScaleFactor, Flags);
3017
3018 return DAG.getNode(ISD::SELECT, SL, VT, NeedsScaling, AdjustedResult, MulExps,
3019 Flags);
3020}
3021
3023 EVT VT = Op.getValueType();
3027 const bool IsExp10 = Op.getOpcode() == ISD::FEXP10;
3028
3030
3031 if (allowApproxFunc(DAG, Flags))
3033
3036
3037
3038
3039
3040
3045 }
3046
3047 assert(VT == MVT::f32);
3048
3049
3050
3054 }
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3082
3086 const float cc_exp = 0x1.4ae0bep-26f;
3087 const float c_exp10 = 0x1.a934f0p+1f;
3088 const float cc_exp10 = 0x1.2f346ep-24f;
3089
3092
3097 } else {
3098 const float ch_exp = 0x1.714000p+0f;
3099 const float cl_exp = 0x1.47652ap-12f;
3100
3101 const float ch_exp10 = 0x1.a92000p+1f;
3102 const float cl_exp10 = 0x1.4f0978p-11f;
3103
3106
3112
3114
3116 SDValue Mad0 = getMad(DAG, SL, VT, XL, CH, XLCL, Flags);
3117 PL = getMad(DAG, SL, VT, XH, CL, Mad0, Flags);
3118 }
3119
3121
3122
3124
3128
3130
3131 SDValue UnderflowCheckConst =
3132 DAG.getConstantFP(IsExp10 ? -0x1.66d3e8p+5f : -0x1.9d1da0p+6f, SL, VT);
3133
3138
3141
3142 if (!Flags.hasNoInfs() && .NoInfsFPMath) {
3143 SDValue OverflowCheckConst =
3144 DAG.getConstantFP(IsExp10 ? 0x1.344136p+5f : 0x1.62e430p+6f, SL, VT);
3150 }
3151
3152 return R;
3153}
3154
3157}
3158
3161}
3162
3166 auto Opc = Op.getOpcode();
3167 auto Arg = Op.getOperand(0u);
3168 auto ResultVT = Op.getValueType();
3169
3170 if (ResultVT != MVT::i8 && ResultVT != MVT::i16)
3171 return {};
3172
3174 assert(ResultVT == Arg.getValueType());
3175
3176 const uint64_t NumBits = ResultVT.getFixedSizeInBits();
3179
3182 NewOp = DAG.getNode(ISD::SHL, SL, MVT::i32, NewOp, NumExtBits);
3183 NewOp = DAG.getNode(Opc, SL, MVT::i32, NewOp);
3184 } else {
3186 NewOp = DAG.getNode(Opc, SL, MVT::i32, NewOp);
3187 NewOp = DAG.getNode(ISD::SUB, SL, MVT::i32, NewOp, NumExtBits);
3188 }
3189
3191}
3192
3196
3200
3203 bool Is64BitScalar = !Src->isDivergent() && Src.getValueType() == MVT::i64;
3204
3205 if (Src.getValueType() == MVT::i32 || Is64BitScalar) {
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216 SDValue NewOpr = DAG.getNode(NewOpc, SL, MVT::i32, Src);
3217 if (!ZeroUndef) {
3219 Op.getValueType().getScalarSizeInBits(), SL, MVT::i32);
3220 NewOpr = DAG.getNode(ISD::UMIN, SL, MVT::i32, NewOpr, ConstVal);
3221 }
3223 }
3224
3227
3230
3231
3232
3233
3234
3235
3238 if (Ctlz)
3239 OprLo = DAG.getNode(AddOpc, SL, MVT::i32, OprLo, Const32);
3240 else
3241 OprHi = DAG.getNode(AddOpc, SL, MVT::i32, OprHi, Const32);
3242
3244 NewOpr = DAG.getNode(ISD::UMIN, SL, MVT::i32, OprLo, OprHi);
3245 if (!ZeroUndef) {
3247 NewOpr = DAG.getNode(ISD::UMIN, SL, MVT::i32, NewOpr, Const64);
3248 }
3249
3251}
3252
3254 bool Signed) const {
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3283
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3315 OppositeSign);
3316
3318
3319
3322 ShAmt = DAG.getNode(ISD::UMIN, SL, MVT::i32, ShAmt, MaxShAmt);
3323 } else {
3325
3326
3333 }
3334
3336
3337 }
3338
3340
3342
3343
3346
3348
3349 unsigned Opc =
3351 SDValue FVal = DAG.getNode(Opc, SL, MVT::f32, Norm);
3352
3353
3354
3356 ShAmt);
3357
3358 if (Subtarget->isGCN())
3360
3361
3362
3363
3370
3374 IVal = DAG.getNode(ISD::OR, SL, MVT::i32, IVal, Sign);
3375 }
3377}
3378
3380 bool Signed) const {
3383
3386
3388 SL, MVT::f64, Hi);
3389
3391
3394
3396}
3397
3400
3401 EVT DestVT = Op.getValueType();
3403 EVT SrcVT = Src.getValueType();
3404
3405 if (SrcVT == MVT::i16) {
3406 if (DestVT == MVT::f16)
3407 return Op;
3409
3410
3413 }
3414
3415 if (DestVT == MVT::bf16) {
3420 }
3421
3422 if (SrcVT != MVT::i64)
3423 return Op;
3424
3425 if (Subtarget->has16BitInsts() && DestVT == MVT::f16) {
3427
3433
3434 return FPRound;
3435 }
3436
3437 if (DestVT == MVT::f32)
3439
3440 assert(DestVT == MVT::f64);
3442}
3443
3446 EVT DestVT = Op.getValueType();
3447
3449 EVT SrcVT = Src.getValueType();
3450
3451 if (SrcVT == MVT::i16) {
3452 if (DestVT == MVT::f16)
3453 return Op;
3454
3456
3459 }
3460
3461 if (DestVT == MVT::bf16) {
3466 }
3467
3468 if (SrcVT != MVT::i64)
3469 return Op;
3470
3471
3472
3473 if (Subtarget->has16BitInsts() && DestVT == MVT::f16) {
3476
3482
3483 return FPRound;
3484 }
3485
3486 if (DestVT == MVT::f32)
3488
3489 assert(DestVT == MVT::f64);
3491}
3492
3494 bool Signed) const {
3496
3498 EVT SrcVT = Src.getValueType();
3499
3500 assert(SrcVT == MVT::f32 || SrcVT == MVT::f64);
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3513 if (Signed && SrcVT == MVT::f32) {
3514
3515
3516
3517
3518
3523 }
3524
3526 if (SrcVT == MVT::f64) {
3528 llvm::bit_cast(UINT64_C( 0x3df0000000000000)), SL,
3529 SrcVT);
3531 llvm::bit_cast(UINT64_C( 0xc1f0000000000000)), SL,
3532 SrcVT);
3533 } else {
3535 llvm::bit_cast(UINT32_C( 0x2f800000)), SL, SrcVT);
3537 llvm::bit_cast(UINT32_C( 0xcf800000)), SL, SrcVT);
3538 }
3539
3541
3543
3545
3548 SL, MVT::i32, FloorMul);
3550
3553
3554 if (Signed && SrcVT == MVT::f32) {
3556
3559
3560 Result =
3562 DAG.getNode(ISD::XOR, SL, MVT::i64, Result, Sign), Sign);
3563 }
3564
3565 return Result;
3566}
3567
3571
3572
3575
3577
3579 }
3580
3582
3583
3584 const unsigned ExpMask = 0x7ff;
3585 const unsigned ExpBiasf64 = 1023;
3586 const unsigned ExpBiasf16 = 15;
3598
3599
3601 DAG.getConstant(-ExpBiasf64 + ExpBiasf16, DL, MVT::i32));
3602
3607
3610 MaskedSig = DAG.getNode(ISD::OR, DL, MVT::i32, MaskedSig, U);
3611
3614
3615
3619
3620
3624
3625
3627 One, E);
3631
3634
3639
3651
3656
3657
3662
3665}
3666
3670 unsigned OpOpcode = Op.getOpcode();
3671 EVT SrcVT = Src.getValueType();
3672 EVT DestVT = Op.getValueType();
3673
3674
3675 if (SrcVT == MVT::f16 && DestVT == MVT::i16)
3676 return Op;
3677
3678 if (SrcVT == MVT::bf16) {
3681 return DAG.getNode(Op.getOpcode(), DL, DestVT, PromotedSrc);
3682 }
3683
3684
3685 if (DestVT == MVT::i16 && (SrcVT == MVT::f32 || SrcVT == MVT::f64)) {
3687
3688 SDValue FpToInt32 = DAG.getNode(OpOpcode, DL, MVT::i32, Src);
3690 }
3691
3692 if (DestVT != MVT::i64)
3693 return Op;
3694
3695 if (SrcVT == MVT::f16 ||
3696 (SrcVT == MVT::f32 && Src.getOpcode() == ISD::FP16_TO_FP)) {
3698
3699 SDValue FpToInt32 = DAG.getNode(OpOpcode, DL, MVT::i32, Src);
3700 unsigned Ext =
3702 return DAG.getNode(Ext, DL, MVT::i64, FpToInt32);
3703 }
3704
3705 if (SrcVT == MVT::f32 || SrcVT == MVT::f64)
3707
3709}
3710
3713 EVT ExtraVT = cast(Op.getOperand(1))->getVT();
3714 MVT VT = Op.getSimpleValueType();
3716
3718
3721
3722
3726
3728 for (unsigned I = 0; I < NElts; ++I)
3730
3732}
3733
3734
3735
3736
3737
3740}
3741
3743 EVT VT = Op.getValueType();
3744 return VT.getSizeInBits() >= 24 &&
3745
3747}
3748
3754
3757 unsigned NewOpcode = Node24->getOpcode();
3758 if (IsIntrin) {
3760 switch (IID) {
3761 case Intrinsic::amdgcn_mul_i24:
3763 break;
3764 case Intrinsic::amdgcn_mul_u24:
3766 break;
3767 case Intrinsic::amdgcn_mulhi_i24:
3769 break;
3770 case Intrinsic::amdgcn_mulhi_u24:
3772 break;
3773 default:
3775 }
3776 }
3777
3779
3780
3781
3782
3785 if (DemandedLHS || DemandedRHS)
3787 DemandedLHS ? DemandedLHS : LHS,
3788 DemandedRHS ? DemandedRHS : RHS);
3789
3790
3791
3793 return SDValue(Node24, 0);
3795 return SDValue(Node24, 0);
3796
3798}
3799
3800template
3803 if (Width + Offset < 32) {
3805 IntTy Result = static_cast<IntTy>(Shl) >> (32 - Width);
3806 if constexpr (std::is_signed_v) {
3808 } else {
3810 }
3811 }
3812
3814}
3815
3818 if (MemSDNode *M = dyn_cast(U)) {
3819 if (M->isVolatile())
3820 return true;
3821 }
3822 }
3823
3824 return false;
3825}
3826
3828
3830 return false;
3831
3833 return false;
3834
3836
3838 return false;
3839
3840 if (Size == 3 || (Size > 4 && (Size % 4 != 0)))
3841 return false;
3842
3843 return true;
3844}
3845
3846
3847
3852
3856
3860
3864 unsigned IsFast;
3866
3867
3868
3869
3874
3877
3879 }
3880
3881 if (!IsFast)
3883 }
3884
3887
3889
3893
3897}
3898
3899
3900
3905
3909
3912
3917 unsigned IsFast;
3919
3920
3921
3922
3923
3928
3930 }
3931
3932 if (!IsFast)
3934 }
3935
3938
3941
3942
3943
3944 bool OtherUses = !Val.hasOneUse();
3946 if (OtherUses) {
3949 }
3950
3953}
3954
3955
3956
3957
3961 SDValue N0 = N->getOperand(0);
3962
3963
3964
3966 SDValue N1 = N->getOperand(1);
3967 EVT ExtVT = cast(N1)->getVT();
3969
3971 EVT SrcVT = Src.getValueType();
3972 if (SrcVT.bitsGE(ExtVT)) {
3973 SDValue NewInReg = DAG.getNode(N->getOpcode(), SL, SrcVT, Src, N1);
3975 }
3976 }
3977
3979}
3980
3983 unsigned IID = N->getConstantOperandVal(0);
3984 switch (IID) {
3985 case Intrinsic::amdgcn_mul_i24:
3986 case Intrinsic::amdgcn_mul_u24:
3987 case Intrinsic::amdgcn_mulhi_i24:
3988 case Intrinsic::amdgcn_mulhi_u24:
3990 case Intrinsic::amdgcn_fract:
3991 case Intrinsic::amdgcn_rsq:
3992 case Intrinsic::amdgcn_rcp_legacy:
3993 case Intrinsic::amdgcn_rsq_legacy:
3994 case Intrinsic::amdgcn_rsq_clamp: {
3995
3996 SDValue Src = N->getOperand(1);
3997 return Src.isUndef() ? Src : SDValue();
3998 }
3999 case Intrinsic::amdgcn_frexp_exp: {
4000
4001
4002
4003 SDValue Src = N->getOperand(1);
4005 if (PeekSign == Src)
4008 0);
4009 }
4010 default:
4012 }
4013}
4014
4015
4016
4019 unsigned Opc, SDValue LHS,
4024
4027
4030
4031
4032
4035
4038}
4039
4042 EVT VT = N->getValueType(0);
4043
4045 if ()
4047
4049 unsigned RHSVal = RHS->getZExtValue();
4050 if (!RHSVal)
4051 return LHS;
4052
4055
4056 switch (LHS->getOpcode()) {
4057 default:
4058 break;
4063
4064 if (VT == MVT::i32 && RHSVal == 16 && X.getValueType() == MVT::i16 &&
4066
4067
4069 { DAG.getConstant(0, SL, MVT::i16), LHS->getOperand(0) });
4071 }
4072
4073
4074 if (VT != MVT::i64)
4075 break;
4078 if (LZ < RHSVal)
4079 break;
4080 EVT XVT = X.getValueType();
4083 }
4084 }
4085
4086 if (VT != MVT::i64)
4088
4089
4090
4091
4092
4093
4094 if (RHSVal < 32)
4096
4098
4101
4103
4106}
4107
4110 if (N->getValueType(0) != MVT::i64)
4112
4113 const ConstantSDNode *RHS = dyn_cast(N->getOperand(1));
4114 if ()
4116
4119 unsigned RHSVal = RHS->getZExtValue();
4120
4121
4122 if (RHSVal == 32) {
4126
4129 }
4130
4131
4132 if (RHSVal == 63) {
4138 }
4139
4141}
4142
4145 auto *RHS = dyn_cast(N->getOperand(1));
4146 if ()
4148
4149 EVT VT = N->getValueType(0);
4151 unsigned ShiftAmt = RHS->getZExtValue();
4154
4155
4156
4158 if (auto *Mask = dyn_cast(LHS.getOperand(1))) {
4159 unsigned MaskIdx, MaskLen;
4160 if (Mask->getAPIntValue().isShiftedMask(MaskIdx, MaskLen) &&
4161 MaskIdx == ShiftAmt) {
4166 }
4167 }
4168 }
4169
4170 if (VT != MVT::i64)
4172
4173 if (ShiftAmt < 32)
4175
4176
4177
4178
4180
4182
4185
4187
4189}
4190
4195 EVT VT = N->getValueType(0);
4196 SDValue Src = N->getOperand(0);
4197
4198
4200 SDValue Vec = Src.getOperand(0);
4208 }
4209
4211 }
4212 }
4213 }
4214
4215
4216
4217
4220 if (2 * K->getZExtValue() == Src.getValueType().getScalarSizeInBits()) {
4229 }
4230
4232 }
4233 }
4234 }
4235 }
4236
4237
4238
4239
4240
4242 EVT SrcVT = Src.getValueType();
4244 (Src.getOpcode() == ISD::SRL ||
4245 Src.getOpcode() == ISD::SRA ||
4246 Src.getOpcode() == ISD::SHL)) {
4247 SDValue Amt = Src.getOperand(1);
4249
4250
4251
4252
4253
4254 const unsigned MaxCstSize =
4260
4263 Src.getOperand(0));
4265
4269 }
4270
4271 SDValue ShrunkShift = DAG.getNode(Src.getOpcode(), SL, MidVT,
4272 Trunc, Amt);
4274 }
4275 }
4276 }
4277
4279}
4280
4281
4282
4283
4284
4287 if (Size <= 32) {
4289 return DAG.getNode(MulOpc, SL, MVT::i32, N0, N1);
4290 }
4291
4294
4295 SDValue MulLo = DAG.getNode(MulLoOpc, SL, MVT::i32, N0, N1);
4296 SDValue MulHi = DAG.getNode(MulHiOpc, SL, MVT::i32, N0, N1);
4297
4299}
4300
4301
4302
4304 if (V->getOpcode() != ISD::ADD)
4306
4308}
4309
4313 EVT VT = N->getValueType(0);
4314
4315
4316
4317
4318
4319 if (->isDivergent())
4321
4325
4328
4329 SDValue N0 = N->getOperand(0);
4330 SDValue N1 = N->getOperand(1);
4331
4332
4333
4334
4335
4338 if (!AddOp)
4340
4341 if (V.hasOneUse() || all_of(V->users(), [](const SDNode *U) -> bool {
4342 return U->getOpcode() == ISD::MUL;
4343 }))
4344 return AddOp;
4345
4347 };
4348
4349
4350
4351 if (SDValue MulOper = IsFoldableAdd(N0)) {
4352 SDValue MulVal = DAG.getNode(N->getOpcode(), DL, VT, N1, MulOper);
4354 }
4355
4356 if (SDValue MulOper = IsFoldableAdd(N1)) {
4357 SDValue MulVal = DAG.getNode(N->getOpcode(), DL, VT, N0, MulOper);
4359 }
4360
4361
4364
4365
4366
4367
4368
4371
4374
4376
4381 } else if (Subtarget->hasMulI24() && isI24(N0, DAG) && isI24(N1, DAG)) {
4385 } else {
4387 }
4388
4389
4390
4392}
4393
4397 if (N->getValueType(0) != MVT::i32)
4399
4402
4404 SDValue N0 = N->getOperand(0);
4405 SDValue N1 = N->getOperand(1);
4406
4407
4408
4409
4410
4415
4416
4417
4418 unsigned LoOpcode = 0;
4419 unsigned HiOpcode = 0;
4426 }
4427 } else {
4433 }
4434 }
4435 if (!LoOpcode)
4437
4442}
4443
4446 EVT VT = N->getValueType(0);
4447
4450
4451
4452
4453
4454
4455
4456
4457 if (Subtarget->hasSMulHi() && ->isDivergent())
4459
4462
4463 SDValue N0 = N->getOperand(0);
4464 SDValue N1 = N->getOperand(1);
4465
4466 if ((N0, DAG) ||
(N1, DAG))
4468
4471
4475}
4476
4479 EVT VT = N->getValueType(0);
4480
4483
4484
4485
4486
4487
4488
4489
4490 if (Subtarget->hasSMulHi() && ->isDivergent())
4492
4495
4496 SDValue N0 = N->getOperand(0);
4497 SDValue N1 = N->getOperand(1);
4498
4499 if ((N0, DAG) ||
(N1, DAG))
4501
4504
4508}
4509
4513 unsigned Opc) const {
4514 EVT VT = Op.getValueType();
4516 if (LegalVT != MVT::i32 && (Subtarget->has16BitInsts() &&
4517 LegalVT != MVT::i16))
4519
4520 if (VT != MVT::i32)
4522
4524 if (VT != MVT::i32)
4526
4527 return FFBX;
4528}
4529
4530
4531
4532
4533
4534
4535
4536
4542
4544 ISD::CondCode CCOpcode = cast(Cond.getOperand(2))->get();
4546
4547
4548
4552 unsigned Opc =
4554 return getFFBX_U32(DAG, CmpLHS, SL, Opc);
4555 }
4556
4557
4558
4562 unsigned Opc =
4564
4565 return getFFBX_U32(DAG, CmpLHS, SL, Opc);
4566 }
4567
4569}
4570
4572 unsigned Op,
4573 const SDLoc &SL,
4579
4583 return DAG.getNode(Op, SL, VT, NewSelect);
4584}
4585
4586
4587
4588
4589
4590
4591
4592
4600
4601 EVT VT = N.getValueType();
4606
4609 }
4610
4611 bool Inv = false;
4614 Inv = true;
4615 }
4616
4617
4622
4623
4626
4627
4628 bool ShouldFoldNeg = true;
4629
4631 unsigned Opc = NewLHS.getOpcode();
4633 ShouldFoldNeg = false;
4635 ShouldFoldNeg = false;
4636 }
4637
4638 if (ShouldFoldNeg) {
4641
4642
4643
4644
4645
4646
4647
4651
4654
4657
4658 if (Inv)
4660
4662 Cond, NewLHS, NewRHS);
4664 return DAG.getNode(LHS.getOpcode(), SL, VT, NewSelect);
4665 }
4666 }
4667
4669}
4670
4674 return Folded;
4675
4679
4680 EVT VT = N->getValueType(0);
4684
4685 SDValue True = N->getOperand(1);
4686 SDValue False = N->getOperand(2);
4687
4688 if (Cond.hasOneUse()) {
4692
4693
4694
4695
4698 getSetCCInverse(cast(CC)->get(), LHS.getValueType());
4699
4702 }
4703
4707
4708
4710 }
4711 }
4712
4713
4715}
4716
4721
4725}
4726
4727
4728
4731 if (C->isZero())
4733
4736
4738}
4739
4743 return false;
4744}
4745
4749 return false;
4750}
4751
4753 switch (Opc) {
4770 default:
4772 }
4773}
4774
4775
4776
4778
4779
4780
4781
4783
4784
4786 return false;
4787 } else {
4790 return false;
4791 }
4792
4793 return true;
4794}
4795
4799 SDValue N0 = N->getOperand(0);
4800 EVT VT = N->getValueType(0);
4801
4803
4806
4808 switch (Opc) {
4812
4813
4816
4819 else
4821
4824 else
4826
4829 return SDValue();
4832 return Res;
4833 }
4836
4837
4840
4845 else
4847
4850 return SDValue();
4853 return Res;
4854 }
4857
4860
4861
4865
4870 else
4872
4875 else
4877
4880 return SDValue();
4883 return Res;
4884 }
4893
4894
4895
4896
4897
4900
4901
4902
4905
4909
4911 if (Res.getOpcode() != Opposite)
4912 return SDValue();
4915 return Res;
4916 }
4919 for (unsigned I = 0; I < 3; ++I)
4921
4924 return SDValue();
4925
4929
4932 }
4933
4934 return Res;
4935 }
4939 case ISD::FNEARBYINT:
4949
4950
4952 }
4953
4956
4957
4958
4961 }
4964
4966
4969 }
4970
4973
4974
4977 }
4979
4980
4981
4983
4985 EVT SrcVT = Src.getValueType();
4986
4987
4991 }
4993
4994
4996 }
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5019
5021 Ops.back() = CastBack;
5026
5029 return Result;
5030 }
5031
5034
5035
5036
5037
5038
5043
5046
5048 NegRHS);
5049 }
5050
5052 }
5053 default:
5055 }
5056}
5057
5061 SDValue N0 = N->getOperand(0);
5062
5065
5068 assert(!Subtarget->has16BitInsts() && "should only see if f16 is illegal");
5071 EVT SrcVT = Src.getValueType();
5072
5073
5077 }
5078 default:
5080 }
5081}
5082
5085 const auto *CFP = dyn_cast(N->getOperand(0));
5086 if (!CFP)
5088
5089
5090 const APFloat &Val = CFP->getValueAPF();
5093}
5094
5099
5100 switch(N->getOpcode()) {
5101 default:
5102 break;
5104 EVT DestVT = N->getValueType(0);
5105
5106
5107
5108
5109
5110
5112 SDValue Src = N->getOperand(0);
5116 EVT SrcVT = Src.getValueType();
5118
5121
5125 SDValue Elt = Src.getOperand(I);
5127 }
5128
5130 }
5131 }
5132 }
5133
5135 break;
5136
5137
5138
5139
5140
5141 SDValue Src = N->getOperand(0);
5142 if (ConstantSDNode *C = dyn_cast(Src)) {
5144 uint64_t CVal = C->getZExtValue();
5149 }
5150
5152 const APInt &Val = C->getValueAPF().bitcastToAPInt();
5158
5160 }
5161
5162 break;
5163 }
5166 break;
5167
5169 }
5172 break;
5173
5175 }
5178 break;
5179
5181 }
5189 return Simplified;
5190 break;
5191 }
5210 assert(->getValueType(0).isVector() &&
5211 "Vector handling of BFE not implemented");
5212 ConstantSDNode *Width = dyn_cast(N->getOperand(2));
5213 if (!Width)
5214 break;
5215
5217 if (WidthVal == 0)
5219
5222 break;
5223
5224 SDValue BitsFrom = N->getOperand(0);
5226
5228
5229 if (OffsetVal == 0) {
5230
5231 unsigned SignBits = Signed ? (32 - WidthVal + 1) : (32 - WidthVal);
5232
5234 if (OpSignBits >= SignBits)
5235 return BitsFrom;
5236
5239
5240
5241
5242
5243
5244
5247 }
5248
5250 }
5251
5252 if (ConstantSDNode *CVal = dyn_cast(BitsFrom)) {
5254 return constantFoldBFE<int32_t>(DAG,
5255 CVal->getSExtValue(),
5256 OffsetVal,
5257 WidthVal,
5258 DL);
5259 }
5260
5261 return constantFoldBFE<uint32_t>(DAG,
5262 CVal->getZExtValue(),
5263 OffsetVal,
5264 WidthVal,
5265 DL);
5266 }
5267
5268 if ((OffsetVal + WidthVal) >= 32 &&
5269 !(Subtarget->hasSDWA() && OffsetVal == 16 && WidthVal == 16)) {
5272 BitsFrom, ShiftVal);
5273 }
5274
5277 OffsetVal,
5278 OffsetVal + WidthVal);
5279
5287 }
5288 }
5289
5290 break;
5291 }
5305 SDValue N0 = N->getOperand(0);
5306 SDValue N1 = N->getOperand(1);
5307 SDValue N2 = N->getOperand(2);
5308 EVT VT = N->getValueType(0);
5309
5310
5311
5315 if (N0CFP && N1CFP && N2CFP) {
5316 const auto FTZ = [](const APFloat &V) {
5317 if (V.isDenormal()) {
5318 APFloat Zero(V.getSemantics(), 0);
5319 return V.isNegative() ? -Zero : Zero;
5320 }
5321 return V;
5322 };
5323
5328 V0 = FTZ(V0);
5331 }
5332 break;
5333 }
5334 }
5336}
5337
5338
5339
5340
5341
5345 const SDLoc &SL,
5346 bool RawReg) const {
5350
5351 if (.isLiveIn(Reg)) {
5352 VReg = MRI.createVirtualRegister(RC);
5353 MRI.addLiveIn(Reg, VReg);
5354 } else {
5355 VReg = MRI.getLiveInVirtReg(Reg);
5356 }
5357
5358 if (RawReg)
5360
5362}
5363
5364
5365
5371 return I;
5372 }
5373 }
5374
5376}
5377
5380 const SDLoc &SL,
5381 int64_t Offset) const {
5385
5388
5392}
5393
5395 const SDLoc &SL,
5398 int64_t Offset) const {
5402
5404
5406 DAG.getCopyFromReg(Chain, SL, Info->getStackPtrOffsetReg(), MVT::i32);
5410 return Store;
5411}
5412
5417 assert(Arg && "Attempting to load missing argument");
5418
5422
5424 return V;
5425
5426 unsigned Mask = Arg.getMask();
5427 unsigned Shift = llvm::countr_zero(Mask);
5431 DAG.getConstant(Mask >> Shift, SL, VT));
5432}
5433
5439 alignTo(ExplicitKernArgSize, Alignment) + ExplicitArgOffset;
5440 switch (Param) {
5442 return ArgOffset;
5449 }
5451}
5452
5457}
5458
5459#define NODE_NAME_CASE(node) case AMDGPUISD::node: return #node;
5460
5464
5466
5467
5613 }
5614 return nullptr;
5615}
5616
5619 int &RefinementSteps,
5620 bool &UseOneConstNR,
5621 bool Reciprocal) const {
5623
5624 if (VT == MVT::f32) {
5625 RefinementSteps = 0;
5627 }
5628
5629
5630
5631
5633}
5634
5637 int &RefinementSteps) const {
5639
5640 if (VT == MVT::f32) {
5641
5642
5643
5644
5645
5646 RefinementSteps = 0;
5648 }
5649
5650
5651
5652
5654}
5655
5657 switch (ID) {
5658 case Intrinsic::amdgcn_workitem_id_x:
5659 return 0;
5660 case Intrinsic::amdgcn_workitem_id_y:
5661 return 1;
5662 case Intrinsic::amdgcn_workitem_id_z:
5663 return 2;
5664 default:
5666 }
5667}
5668
5672
5673 Known.resetAll();
5674
5675 unsigned Opc = Op.getOpcode();
5676
5677 switch (Opc) {
5678 default:
5679 break;
5683 break;
5684 }
5685
5688 ConstantSDNode *CWidth = dyn_cast(Op.getOperand(2));
5689 if (!CWidth)
5690 return;
5691
5693
5696
5697 break;
5698 }
5701
5702
5704 break;
5705 }
5713
5714 if (TrailZ >= 32)
5715 break;
5716
5717
5718 LHSKnown = LHSKnown.trunc(24);
5719 RHSKnown = RHSKnown.trunc(24);
5720
5724 unsigned MaxValBits = LHSValBits + RHSValBits;
5725 if (MaxValBits > 32)
5726 break;
5727 unsigned SignBits = 32 - MaxValBits + 1;
5728 bool LHSNegative = LHSKnown.isNegative();
5731 bool RHSNegative = RHSKnown.isNegative();
5734
5735 if ((LHSNonNegative && RHSNonNegative) || (LHSNegative && RHSNegative))
5737 else if ((LHSNegative && RHSPositive) || (LHSPositive && RHSNegative))
5739 } else {
5742 unsigned MaxValBits = LHSValBits + RHSValBits;
5743 if (MaxValBits >= 32)
5744 break;
5746 }
5747 break;
5748 }
5750 ConstantSDNode *CMask = dyn_cast(Op.getOperand(2));
5751 if (!CMask)
5752 return;
5753
5757
5758 for (unsigned I = 0; I < 32; I += 8) {
5759 unsigned SelBits = Sel & 0xff;
5760 if (SelBits < 4) {
5761 SelBits *= 8;
5764 } else if (SelBits < 7) {
5765 SelBits = (SelBits & 3) * 8;
5768 } else if (SelBits == 0x0c) {
5769 Known.Zero |= 0xFFull << I;
5770 } else if (SelBits > 0x0c) {
5771 Known.One |= 0xFFull << I;
5772 }
5773 Sel >>= 8;
5774 }
5775 break;
5776 }
5779 break;
5780 }
5783 break;
5784 }
5786 auto *GA = cast(Op.getOperand(0).getNode());
5787 Align Alignment = GA->getGlobal()->getPointerAlignment(DAG.getDataLayout());
5788
5791 break;
5792 }
5801 break;
5802
5805 break;
5806
5809 break;
5810
5811
5813 Known.One = Known0.One & Known1.One & Known2.One;
5814 break;
5815 }
5817 unsigned IID = Op.getConstantOperandVal(0);
5818 switch (IID) {
5819 case Intrinsic::amdgcn_workitem_id_x:
5820 case Intrinsic::amdgcn_workitem_id_y:
5821 case Intrinsic::amdgcn_workitem_id_z: {
5825 break;
5826 }
5827 default:
5828 break;
5829 }
5830 }
5831 }
5832}
5833
5836 unsigned Depth) const {
5837 switch (Op.getOpcode()) {
5839 ConstantSDNode *Width = dyn_cast(Op.getOperand(2));
5840 if (!Width)
5841 return 1;
5842
5843 unsigned SignBits = 32 - Width->getZExtValue() + 1;
5845 return SignBits;
5846
5847
5849 return std::max(SignBits, Op0SignBits);
5850 }
5851
5853 ConstantSDNode *Width = dyn_cast(Op.getOperand(2));
5854 return Width ? 32 - (Width->getZExtValue() & 0x1f) : 1;
5855 }
5856
5859 return 31;
5861 return 25;
5863 return 17;
5865 return 24;
5867 return 16;
5869 return 16;
5877 if (Tmp2 == 1)
5878 return 1;
5879
5881 if (Tmp1 == 1)
5882 return 1;
5883
5885 if (Tmp0 == 1)
5886 return 1;
5887
5888 return std::min({Tmp0, Tmp1, Tmp2});
5889 }
5890 default:
5891 return 1;
5892 }
5893}
5894
5898 unsigned Depth) const {
5900 if ()
5901 return 1;
5902
5903
5904 switch (MI->getOpcode()) {
5905 case AMDGPU::G_AMDGPU_BUFFER_LOAD_SBYTE:
5906 return 25;
5907 case AMDGPU::G_AMDGPU_BUFFER_LOAD_SSHORT:
5908 return 17;
5909 case AMDGPU::G_AMDGPU_BUFFER_LOAD_UBYTE:
5910 return 24;
5911 case AMDGPU::G_AMDGPU_BUFFER_LOAD_USHORT:
5912 return 16;
5913 case AMDGPU::G_AMDGPU_SMED3:
5914 case AMDGPU::G_AMDGPU_UMED3: {
5915 auto [Dst, Src0, Src1, Src2] = MI->getFirst4Regs();
5916 unsigned Tmp2 = Analysis.computeNumSignBits(Src2, DemandedElts, Depth + 1);
5917 if (Tmp2 == 1)
5918 return 1;
5919 unsigned Tmp1 = Analysis.computeNumSignBits(Src1, DemandedElts, Depth + 1);
5920 if (Tmp1 == 1)
5921 return 1;
5922 unsigned Tmp0 = Analysis.computeNumSignBits(Src0, DemandedElts, Depth + 1);
5923 if (Tmp0 == 1)
5924 return 1;
5925 return std::min({Tmp0, Tmp1, Tmp2});
5926 }
5927 default:
5928 return 1;
5929 }
5930}
5931
5934 bool SNaN,
5935 unsigned Depth) const {
5936 unsigned Opcode = Op.getOpcode();
5937 switch (Opcode) {
5940 if (SNaN)
5941 return true;
5942
5943
5944
5945 return false;
5946 }
5949 if (SNaN)
5950 return true;
5953 }
5960 if (SNaN)
5961 return true;
5965 }
5970 return true;
5971
5976 if (SNaN)
5977 return true;
5978
5979
5980 return false;
5981 }
5984 if (SNaN)
5985 return true;
5987 }
5991
5992 return SNaN;
5995
5996 return SNaN;
5997 }
5999 unsigned IntrinsicID = Op.getConstantOperandVal(0);
6000
6001 switch (IntrinsicID) {
6002 case Intrinsic::amdgcn_cubeid:
6003 return true;
6004
6005 case Intrinsic::amdgcn_frexp_mant: {
6006 if (SNaN)
6007 return true;
6009 }
6010 case Intrinsic::amdgcn_cvt_pkrtz: {
6011 if (SNaN)
6012 return true;
6015 }
6016 case Intrinsic::amdgcn_rcp:
6017 case Intrinsic::amdgcn_rsq:
6018 case Intrinsic::amdgcn_rcp_legacy:
6019 case Intrinsic::amdgcn_rsq_legacy:
6020 case Intrinsic::amdgcn_rsq_clamp: {
6021 if (SNaN)
6022 return true;
6023
6024
6025 return false;
6026 }
6027 case Intrinsic::amdgcn_trig_preop:
6028 case Intrinsic::amdgcn_fdot2:
6029
6030 return SNaN;
6031 case Intrinsic::amdgcn_fma_legacy:
6032 if (SNaN)
6033 return true;
6037 default:
6038 return false;
6039 }
6040 }
6041 default:
6042 return false;
6043 }
6044}
6045
6048 return MRI.hasOneNonDBGUse(N0);
6049}
unsigned const MachineRegisterInfo * MRI
static LLVM_READONLY bool hasSourceMods(const MachineInstr &MI)
static bool isInv2Pi(const APFloat &APF)
static LLVM_READONLY bool opMustUseVOP3Encoding(const MachineInstr &MI, const MachineRegisterInfo &MRI)
returns true if the operation will definitely need to use a 64-bit encoding, and thus will use a VOP3...
static unsigned inverseMinMax(unsigned Opc)
static SDValue extractF64Exponent(SDValue Hi, const SDLoc &SL, SelectionDAG &DAG)
static unsigned workitemIntrinsicDim(unsigned ID)
static int getOrCreateFixedStackObject(MachineFrameInfo &MFI, unsigned Size, int64_t Offset)
static SDValue constantFoldBFE(SelectionDAG &DAG, IntTy Src0, uint32_t Offset, uint32_t Width, const SDLoc &DL)
static SDValue getMad(SelectionDAG &DAG, const SDLoc &SL, EVT VT, SDValue X, SDValue Y, SDValue C, SDNodeFlags Flags=SDNodeFlags())
static SDValue getAddOneOp(const SDNode *V)
If V is an add of a constant 1, returns the other operand.
#define NODE_NAME_CASE(node)
static LLVM_READONLY bool selectSupportsSourceMods(const SDNode *N)
Return true if v_cndmask_b32 will support fabs/fneg source modifiers for the type for ISD::SELECT.
static cl::opt< bool > AMDGPUBypassSlowDiv("amdgpu-bypass-slow-div", cl::desc("Skip 64-bit divide for dynamic 32-bit values"), cl::init(true))
static SDValue getMul24(SelectionDAG &DAG, const SDLoc &SL, SDValue N0, SDValue N1, unsigned Size, bool Signed)
static bool fnegFoldsIntoOp(const SDNode *N)
static bool isI24(SDValue Op, SelectionDAG &DAG)
static bool isCttzOpc(unsigned Opc)
static bool isU24(SDValue Op, SelectionDAG &DAG)
static SDValue peekFPSignOps(SDValue Val)
static bool valueIsKnownNeverF32Denorm(SDValue Src)
Return true if it's known that Src can never be an f32 denormal value.
static SDValue distributeOpThroughSelect(TargetLowering::DAGCombinerInfo &DCI, unsigned Op, const SDLoc &SL, SDValue Cond, SDValue N1, SDValue N2)
static SDValue peekFNeg(SDValue Val)
static SDValue simplifyMul24(SDNode *Node24, TargetLowering::DAGCombinerInfo &DCI)
static bool isCtlzOpc(unsigned Opc)
static LLVM_READNONE bool fnegFoldsIntoOpcode(unsigned Opc)
static bool hasVolatileUser(SDNode *Val)
Interface definition of the TargetLowering class that is common to all AMD GPUs.
Contains the definition of a TargetInstrInfo class that is common to all AMD GPUs.
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis Results
block Block Frequency Analysis
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
Analysis containing CSE Info
static cl::opt< unsigned > CostThreshold("dfa-cost-threshold", cl::desc("Maximum cost accepted for the transformation"), cl::Hidden, cl::init(50))
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
Provides analysis for querying information about KnownBits during GISel passes.
static DebugLoc getDebugLoc(MachineBasicBlock::instr_iterator FirstMI, MachineBasicBlock::instr_iterator LastMI)
Return the first found DebugLoc that has a DILocation, given a range of instructions.
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static CCAssignFn * CCAssignFnForCall(CallingConv::ID CC, bool IsVarArg)
static CCAssignFn * CCAssignFnForReturn(CallingConv::ID CC, bool IsVarArg)
static bool isUniformMMO(const MachineMemOperand *MMO)
uint64_t getExplicitKernArgSize() const
static std::optional< uint32_t > getLDSAbsoluteAddress(const GlobalValue &GV)
unsigned allocateLDSGlobal(const DataLayout &DL, const GlobalVariable &GV)
bool isModuleEntryFunction() const
bool hasFminFmaxLegacy() const
Align getAlignmentForImplicitArgPtr() const
bool hasMadMacF32Insts() const
unsigned getMaxWorkitemID(const Function &Kernel, unsigned Dimension) const
Return the maximum workitem ID value in the function, for the given (0, 1, 2) dimension.
bool has16BitInsts() const
bool hasFastFMAF32() const
unsigned getExplicitKernelArgOffset() const
Returns the offset in bytes from the start of the input buffer of the first explicit kernel argument.
static const AMDGPUSubtarget & get(const MachineFunction &MF)
bool hasInv2PiInlineImm() const
bool hasVOP3PInsts() const
static unsigned numBitsSigned(SDValue Op, SelectionDAG &DAG)
SDValue combineFMinMaxLegacy(const SDLoc &DL, EVT VT, SDValue LHS, SDValue RHS, SDValue True, SDValue False, SDValue CC, DAGCombinerInfo &DCI) const
Generate Min/Max node.
unsigned ComputeNumSignBitsForTargetNode(SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth=0) const override
This method can be implemented by targets that want to expose additional information about sign bits ...
SDValue performMulhuCombine(SDNode *N, DAGCombinerInfo &DCI) const
EVT getTypeForExtReturn(LLVMContext &Context, EVT VT, ISD::NodeType ExtendKind) const override
Return the type that should be used to zero or sign extend a zeroext/signext integer return value.
SDValue SplitVectorLoad(SDValue Op, SelectionDAG &DAG) const
Split a vector load into 2 loads of half the vector.
SDValue LowerCONCAT_VECTORS(SDValue Op, SelectionDAG &DAG) const
SDValue performLoadCombine(SDNode *N, DAGCombinerInfo &DCI) const
void analyzeFormalArgumentsCompute(CCState &State, const SmallVectorImpl< ISD::InputArg > &Ins) const
The SelectionDAGBuilder will automatically promote function arguments with illegal types.
SDValue LowerFROUND(SDValue Op, SelectionDAG &DAG) const
SDValue storeStackInputValue(SelectionDAG &DAG, const SDLoc &SL, SDValue Chain, SDValue ArgVal, int64_t Offset) const
bool storeOfVectorConstantIsCheap(bool IsZero, EVT MemVT, unsigned NumElem, unsigned AS) const override
Return true if it is expected to be cheaper to do a store of vector constant with the given size and ...
SDValue LowerEXTRACT_SUBVECTOR(SDValue Op, SelectionDAG &DAG) const
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...
bool shouldCombineMemoryType(EVT VT) const
SDValue splitBinaryBitConstantOpImpl(DAGCombinerInfo &DCI, const SDLoc &SL, unsigned Opc, SDValue LHS, uint32_t ValLo, uint32_t ValHi) const
Split the 64-bit value LHS into two 32-bit components, and perform the binary operation Opc to it wit...
SDValue lowerUnhandledCall(CallLoweringInfo &CLI, SmallVectorImpl< SDValue > &InVals, StringRef Reason) const
SDValue performAssertSZExtCombine(SDNode *N, DAGCombinerInfo &DCI) const
bool isTruncateFree(EVT Src, EVT Dest) const override
bool aggressivelyPreferBuildVectorSources(EVT VecVT) const override
SDValue LowerFCEIL(SDValue Op, SelectionDAG &DAG) const
TargetLowering::NegatibleCost getConstantNegateCost(const ConstantFPSDNode *C) const
SDValue LowerFLOGUnsafe(SDValue Op, const SDLoc &SL, SelectionDAG &DAG, bool IsLog10, SDNodeFlags Flags) const
SDValue performMulhsCombine(SDNode *N, DAGCombinerInfo &DCI) const
bool isSDNodeAlwaysUniform(const SDNode *N) const override
bool isDesirableToCommuteWithShift(const SDNode *N, CombineLevel Level) const override
Return true if it is profitable to move this shift by a constant amount through its operand,...
SDValue LowerFREM(SDValue Op, SelectionDAG &DAG) const
Split a vector store into multiple scalar stores.
SDValue performShlCombine(SDNode *N, DAGCombinerInfo &DCI) const
bool isCheapToSpeculateCtlz(Type *Ty) const override
Return true if it is cheap to speculate a call to intrinsic ctlz.
SDValue LowerSDIVREM(SDValue Op, SelectionDAG &DAG) const
bool isFNegFree(EVT VT) const override
Return true if an fneg operation is free to the point where it is never worthwhile to replace it with...
SDValue LowerFLOG10(SDValue Op, SelectionDAG &DAG) const
SDValue LowerINT_TO_FP64(SDValue Op, SelectionDAG &DAG, bool Signed) const
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...
SDValue LowerFP_TO_FP16(SDValue Op, SelectionDAG &DAG) const
SDValue addTokenForArgument(SDValue Chain, SelectionDAG &DAG, MachineFrameInfo &MFI, int ClobberedFI) const
bool isConstantCheaperToNegate(SDValue N) const
bool isReassocProfitable(MachineRegisterInfo &MRI, Register N0, Register N1) const override
static bool needsDenormHandlingF32(const SelectionDAG &DAG, SDValue Src, SDNodeFlags Flags)
uint32_t getImplicitParameterOffset(const MachineFunction &MF, const ImplicitParameter Param) const
Helper function that returns the byte offset of the given type of implicit parameter.
SDValue LowerFFLOOR(SDValue Op, SelectionDAG &DAG) const
SDValue performSelectCombine(SDNode *N, DAGCombinerInfo &DCI) const
SDValue performFNegCombine(SDNode *N, DAGCombinerInfo &DCI) const
SDValue LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG) const
virtual SDValue LowerGlobalAddress(AMDGPUMachineFunction *MFI, SDValue Op, SelectionDAG &DAG) const
bool isConstantCostlierToNegate(SDValue N) const
SDValue loadInputValue(SelectionDAG &DAG, const TargetRegisterClass *RC, EVT VT, const SDLoc &SL, const ArgDescriptor &Arg) const
SDValue LowerDIVREM24(SDValue Op, SelectionDAG &DAG, bool sign) const
SDValue lowerFEXP10Unsafe(SDValue Op, const SDLoc &SL, SelectionDAG &DAG, SDNodeFlags Flags) const
Emit approx-funcs appropriate lowering for exp10.
SDValue LowerUINT_TO_FP(SDValue Op, SelectionDAG &DAG) const
bool isCheapToSpeculateCttz(Type *Ty) const override
Return true if it is cheap to speculate a call to intrinsic cttz.
SDValue performCtlz_CttzCombine(const SDLoc &SL, SDValue Cond, SDValue LHS, SDValue RHS, DAGCombinerInfo &DCI) const
SDValue performSraCombine(SDNode *N, DAGCombinerInfo &DCI) const
bool isSelectSupported(SelectSupportKind) const override
bool isZExtFree(Type *Src, Type *Dest) const override
Return true if any actual instruction that defines a value of type FromTy implicitly zero-extends the...
SDValue lowerFEXP2(SDValue Op, SelectionDAG &DAG) const
SDValue LowerCall(CallLoweringInfo &CLI, SmallVectorImpl< SDValue > &InVals) const override
This hook must be implemented to lower calls into the specified DAG.
SDValue performSrlCombine(SDNode *N, DAGCombinerInfo &DCI) const
SDValue lowerFEXP(SDValue Op, SelectionDAG &DAG) const
SDValue getIsLtSmallestNormal(SelectionDAG &DAG, SDValue Op, SDNodeFlags Flags) const
bool mayIgnoreSignedZero(SDValue Op) const
SDValue getIsFinite(SelectionDAG &DAG, SDValue Op, SDNodeFlags Flags) const
bool isLoadBitCastBeneficial(EVT, EVT, const SelectionDAG &DAG, const MachineMemOperand &MMO) const final
Return true if the following transform is beneficial: fold (conv (load x)) -> (load (conv*)x) On arch...
bool shouldReduceLoadWidth(SDNode *Load, ISD::LoadExtType ExtType, EVT ExtVT) const override
Return true if it is profitable to reduce a load to a smaller type.
MVT getVectorIdxTy(const DataLayout &) const override
Returns the type to be used for the index operand of: ISD::INSERT_VECTOR_ELT, ISD::EXTRACT_VECTOR_ELT...
std::pair< SDValue, SDValue > splitVector(const SDValue &N, const SDLoc &DL, const EVT &LoVT, const EVT &HighVT, SelectionDAG &DAG) const
Split a vector value into two parts of types LoVT and HiVT.
SDValue LowerFLOGCommon(SDValue Op, SelectionDAG &DAG) const
SDValue foldFreeOpFromSelect(TargetLowering::DAGCombinerInfo &DCI, SDValue N) const
SDValue LowerINT_TO_FP32(SDValue Op, SelectionDAG &DAG, bool Signed) const
bool isFAbsFree(EVT VT) const override
Return true if an fabs operation is free to the point where it is never worthwhile to replace it with...
SDValue loadStackInputValue(SelectionDAG &DAG, EVT VT, const SDLoc &SL, int64_t Offset) const
Similar to CreateLiveInRegister, except value maybe loaded from a stack slot rather than passed in a ...
SDValue LowerFLOG2(SDValue Op, SelectionDAG &DAG) const
static EVT getEquivalentMemType(LLVMContext &Context, EVT VT)
SDValue getSqrtEstimate(SDValue Operand, SelectionDAG &DAG, int Enabled, int &RefinementSteps, bool &UseOneConstNR, bool Reciprocal) const override
Hooks for building estimates in place of slower divisions and square roots.
unsigned computeNumSignBitsForTargetInstr(GISelKnownBits &Analysis, Register R, const APInt &DemandedElts, const MachineRegisterInfo &MRI, unsigned Depth=0) const override
This method can be implemented by targets that want to expose additional information about sign bits ...
SDValue performTruncateCombine(SDNode *N, DAGCombinerInfo &DCI) const
SDValue LowerSINT_TO_FP(SDValue Op, SelectionDAG &DAG) const
static SDValue stripBitcast(SDValue Val)
SDValue CreateLiveInRegister(SelectionDAG &DAG, const TargetRegisterClass *RC, Register Reg, EVT VT, const SDLoc &SL, bool RawReg=false) const
Helper function that adds Reg to the LiveIn list of the DAG's MachineFunction.
SDValue SplitVectorStore(SDValue Op, SelectionDAG &DAG) const
Split a vector store into 2 stores of half the vector.
SDValue LowerCTLZ_CTTZ(SDValue Op, SelectionDAG &DAG) const
SDValue getNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOperations, bool ForCodeSize, NegatibleCost &Cost, unsigned Depth) const override
Return the newly negated expression if the cost is not expensive and set the cost in Cost to indicate...
std::pair< SDValue, SDValue > split64BitValue(SDValue Op, SelectionDAG &DAG) const
Return 64-bit value Op as two 32-bit integers.
SDValue performMulCombine(SDNode *N, DAGCombinerInfo &DCI) const
SDValue getRecipEstimate(SDValue Operand, SelectionDAG &DAG, int Enabled, int &RefinementSteps) const override
Return a reciprocal estimate value for the input operand.
AMDGPUTargetLowering(const TargetMachine &TM, const AMDGPUSubtarget &STI)
SDValue LowerFNEARBYINT(SDValue Op, SelectionDAG &DAG) const
const char * getTargetNodeName(unsigned Opcode) const override
This method returns the name of a target specific DAG node.
SDValue LowerSIGN_EXTEND_INREG(SDValue Op, SelectionDAG &DAG) const
static CCAssignFn * CCAssignFnForReturn(CallingConv::ID CC, bool IsVarArg)
std::pair< SDValue, SDValue > getScaledLogInput(SelectionDAG &DAG, const SDLoc SL, SDValue Op, SDNodeFlags Flags) const
If denormal handling is required return the scaled input to FLOG2, and the check for denormal range.
static CCAssignFn * CCAssignFnForCall(CallingConv::ID CC, bool IsVarArg)
Selects the correct CCAssignFn for a given CallingConvention value.
static bool allUsesHaveSourceMods(const SDNode *N, unsigned CostThreshold=4)
SDValue LowerFROUNDEVEN(SDValue Op, SelectionDAG &DAG) const
bool isFPImmLegal(const APFloat &Imm, EVT VT, bool ForCodeSize) const override
Returns true if the target can instruction select the specified FP immediate natively.
bool isKnownNeverNaNForTargetNode(SDValue Op, const SelectionDAG &DAG, bool SNaN=false, unsigned Depth=0) const override
If SNaN is false,.
static unsigned numBitsUnsigned(SDValue Op, SelectionDAG &DAG)
SDValue lowerFEXPUnsafe(SDValue Op, const SDLoc &SL, SelectionDAG &DAG, SDNodeFlags Flags) const
SDValue LowerFTRUNC(SDValue Op, SelectionDAG &DAG) const
SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const
static bool allowApproxFunc(const SelectionDAG &DAG, SDNodeFlags Flags)
bool ShouldShrinkFPConstant(EVT VT) const override
If true, then instruction selection should seek to shrink the FP constant of the specified type to a ...
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,...
SDValue performStoreCombine(SDNode *N, DAGCombinerInfo &DCI) const
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...
SDValue performRcpCombine(SDNode *N, DAGCombinerInfo &DCI) const
SDValue getLoHalf64(SDValue Op, SelectionDAG &DAG) const
SDValue lowerCTLZResults(SDValue Op, SelectionDAG &DAG) const
SDValue performFAbsCombine(SDNode *N, DAGCombinerInfo &DCI) const
SDValue LowerFP_TO_INT64(SDValue Op, SelectionDAG &DAG, bool Signed) const
static bool shouldFoldFNegIntoSrc(SDNode *FNeg, SDValue FNegSrc)
bool isNarrowingProfitable(SDNode *N, EVT SrcVT, EVT DestVT) const override
Return true if it's profitable to narrow operations of type SrcVT to DestVT.
SDValue LowerFRINT(SDValue Op, SelectionDAG &DAG) const
SDValue performIntrinsicWOChainCombine(SDNode *N, DAGCombinerInfo &DCI) const
SDValue LowerUDIVREM(SDValue Op, SelectionDAG &DAG) const
SDValue performMulLoHiCombine(SDNode *N, DAGCombinerInfo &DCI) const
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...
void LowerUDIVREM64(SDValue Op, SelectionDAG &DAG, SmallVectorImpl< SDValue > &Results) const
SDValue WidenOrSplitVectorLoad(SDValue Op, SelectionDAG &DAG) const
Widen a suitably aligned v3 load.
std::pair< EVT, EVT > getSplitDestVTs(const EVT &VT, SelectionDAG &DAG) const
Split a vector type into two parts.
SDValue getHiHalf64(SDValue Op, SelectionDAG &DAG) const
SDValue combineFMinMaxLegacyImpl(const SDLoc &DL, EVT VT, SDValue LHS, SDValue RHS, SDValue True, SDValue False, SDValue CC, DAGCombinerInfo &DCI) const
bool bitwiseIsEqual(const APFloat &RHS) const
opStatus add(const APFloat &RHS, roundingMode RM)
const fltSemantics & getSemantics() const
opStatus multiply(const APFloat &RHS, roundingMode RM)
static APFloat getSmallestNormalized(const fltSemantics &Sem, bool Negative=false)
Returns the smallest (by magnitude) normalized finite number in the given semantics.
static APFloat getInf(const fltSemantics &Sem, bool Negative=false)
Factory for Positive and Negative Infinity.
Class for arbitrary precision integers.
uint64_t getZExtValue() const
Get zero extended value.
void setHighBits(unsigned hiBits)
Set the top hiBits bits.
void setBitsFrom(unsigned loBit)
Set the top bits starting from loBit.
static APInt getBitsSet(unsigned numBits, unsigned loBit, unsigned hiBit)
Get a value with a block of bits set.
bool ule(const APInt &RHS) const
Unsigned less or equal comparison.
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
void setLowBits(unsigned loBits)
Set the bottom loBits bits.
This class represents an incoming formal argument to a Function.
CCState - This class holds information needed while lowering arguments and return values.
MachineFunction & getMachineFunction() const
LLVMContext & getContext() const
void addLoc(const CCValAssign &V)
static CCValAssign getCustomMem(unsigned ValNo, MVT ValVT, int64_t Offset, MVT LocVT, LocInfo HTP)
const APFloat & getValueAPF() const
bool isNegative() const
Return true if the value is negative.
uint64_t getZExtValue() const
This class represents an Operation in the Expression.
uint64_t getNumOperands() const
bool print(raw_ostream &OS, DIDumpOptions DumpOpts, const DWARFExpression *Expr, DWARFUnit *U) const
A parsed version of the target data layout string in and methods for querying it.
Diagnostic information for unsupported feature in backend.
const DataLayout & getDataLayout() const
Get the data layout of the module this function belongs to.
iterator_range< arg_iterator > args()
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
Module * getParent()
Get the module that this global value is contained inside of...
This is an important class for using LLVM in a threaded context.
void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
This class is used to represent ISD::LOAD nodes.
const SDValue & getBasePtr() const
static auto integer_fixedlen_vector_valuetypes()
unsigned getVectorNumElements() 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()
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
MVT getScalarType() const
If this is a vector, return the element type, otherwise return this.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
int getObjectIndexBegin() const
Return the minimum frame object index.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
DenormalMode getDenormalMode(const fltSemantics &FPType) const
Returns the denormal handling type for the default rounding mode of the function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Representation of each machine instruction.
A description of a memory reference used in the backend.
@ MODereferenceable
The memory access is dereferenceable (i.e., doesn't trap).
@ MOInvariant
The memory access always returns the same value (or traps).
Flags getFlags() const
Return the raw flags of the source value,.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
This is an abstract virtual class for memory operations.
unsigned getAddressSpace() const
Return the address space for the associated pointer.
bool isSimple() const
Returns true if the memory operation is neither atomic or volatile.
MachineMemOperand * getMemOperand() const
Return a MachineMemOperand object describing the memory reference performed by operation.
const SDValue & getChain() const
EVT getMemoryVT() const
Return the type of the in-memory value.
LLVMContext & getContext() const
Get the global data context.
Wrapper class representing virtual and physical registers.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
const DebugLoc & getDebugLoc() const
Represents one node in the SelectionDAG.
ArrayRef< SDUse > ops() const
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
SDVTList getVTList() const
const SDValue & getOperand(unsigned Num) const
uint64_t getConstantOperandVal(unsigned Num) const
Helper method returns the integer value of a ConstantSDNode operand.
iterator_range< user_iterator > users()
Represents a use of a SDNode.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
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.
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
TypeSize getValueSizeInBits() const
Returns the size of the value in bits.
const SDValue & getOperand(unsigned i) const
MVT getSimpleValueType() const
Return the simple ValueType of the referenced return value.
unsigned getOpcode() const
unsigned getNumOperands() const
This class keeps track of the SPI_SP_INPUT_ADDR config register, which tells the hardware which inter...
SIModeRegisterDefaults getMode() const
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
SDValue getExtLoad(ISD::LoadExtType ExtType, const SDLoc &dl, EVT VT, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, EVT MemVT, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
unsigned ComputeMaxSignificantBits(SDValue Op, unsigned Depth=0) const
Get the upper bound on bit size for this Value Op as a signed integer.
const SDValue & getRoot() const
Return the root tag of the SelectionDAG.
SDValue getMergeValues(ArrayRef< SDValue > Ops, const SDLoc &dl)
Create a MERGE_VALUES node from the given operands.
SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
SDValue getShiftAmountConstant(uint64_t Val, EVT VT, const SDLoc &DL)
SDValue getAllOnesConstant(const SDLoc &DL, EVT VT, bool IsTarget=false, bool IsOpaque=false)
void ExtractVectorElements(SDValue Op, SmallVectorImpl< SDValue > &Args, unsigned Start=0, unsigned Count=0, EVT EltVT=EVT())
Append the extracted elements from Start to Count out of the vector Op in Args.
SDValue getSetCC(const SDLoc &DL, EVT VT, SDValue LHS, SDValue RHS, ISD::CondCode Cond, SDValue Chain=SDValue(), bool IsSignaling=false)
Helper function to make it easier to build SetCC's if you just have an ISD::CondCode instead of an SD...
SDValue getConstantFP(double Val, const SDLoc &DL, EVT VT, bool isTarget=false)
Create a ConstantFPSDNode wrapping a constant value.
SDValue getRegister(Register Reg, EVT VT)
SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr)
Loads are not normal binary operators: their result type is not determined by their operands,...
SDValue getNOT(const SDLoc &DL, SDValue Val, EVT VT)
Create a bitwise NOT operation as (XOR Val, -1).
const TargetLowering & getTargetLoweringInfo() const
SDValue getUNDEF(EVT VT)
Return an UNDEF node. UNDEF does not have a useful SDLoc.
SDValue getBuildVector(EVT VT, const SDLoc &DL, ArrayRef< SDValue > Ops)
Return an ISD::BUILD_VECTOR node.
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)
SDValue getSelect(const SDLoc &DL, EVT VT, SDValue Cond, SDValue LHS, SDValue RHS, SDNodeFlags Flags=SDNodeFlags())
Helper function to make it easier to build Select's if you just have operands and don't want to check...
SDValue getZeroExtendInReg(SDValue Op, const SDLoc &DL, EVT VT)
Return the expression required to zero extend the Op value assuming it was the smaller SrcTy value.
const DataLayout & getDataLayout() const
SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
SDValue getTruncStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, EVT SVT, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
void ReplaceAllUsesWith(SDValue From, SDValue To)
Modify anything using 'From' to use 'To' instead.
SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
Helper function to build ISD::STORE nodes.
SDValue getSignedConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
bool isConstantValueOfAnyType(SDValue N) const
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...
const TargetMachine & getTarget() const
SDValue getSelectCC(const SDLoc &DL, SDValue LHS, SDValue RHS, SDValue True, SDValue False, ISD::CondCode Cond)
Helper function to make it easier to build SelectCC's if you just have an ISD::CondCode instead of an...
SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
SDValue getValueType(EVT)
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
bool isKnownNeverNaN(SDValue Op, bool SNaN=false, unsigned Depth=0) const
Test whether the given SDValue (or all elements of it, if it is a vector) is known to never be NaN.
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
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 getVectorIdxConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
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 getFrameIndex(int FI, EVT VT, bool isTarget=false)
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.
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...
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
const SDValue & setRoot(SDValue N)
Set the current root tag of the SelectionDAG.
SDNode * UpdateNodeOperands(SDNode *N, SDValue Op)
Mutate the specified node in-place to have the specified operands.
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
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.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class is used to represent ISD::STORE nodes.
const SDValue & getBasePtr() const
const SDValue & getValue() const
StringRef - Represent a constant reference to a string, i.e.
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...
void setMaxDivRemBitWidthSupported(unsigned SizeInBits)
Set the size in bits of the maximum div/rem the backend supports.
bool PredictableSelectIsExpensive
Tells the code generator that select is more expensive than a branch if the branch is usually predict...
unsigned MaxStoresPerMemcpyOptSize
Likewise for functions with the OptSize attribute.
const TargetMachine & getTargetMachine() const
virtual unsigned getNumRegistersForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT) const
Certain targets require unusual breakdowns of certain types.
unsigned MaxGluedStoresPerMemcpy
Specify max number of store instructions to glue in inlined memcpy.
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...
void addBypassSlowDiv(unsigned int SlowBitWidth, unsigned int FastBitWidth)
Tells the code generator which bitwidths to bypass.
void setMaxLargeFPConvertBitWidthSupported(unsigned SizeInBits)
Set the size in bits of the maximum fp convert the backend supports.
void setMaxAtomicSizeInBitsSupported(unsigned SizeInBits)
Set the maximum atomic operation size supported by the backend.
SelectSupportKind
Enum that describes what type of support for selects the target has.
virtual bool allowsMisalignedMemoryAccesses(EVT, unsigned AddrSpace=0, Align Alignment=Align(1), MachineMemOperand::Flags Flags=MachineMemOperand::MONone, unsigned *=nullptr) const
Determine if the target supports unaligned memory accesses.
unsigned MaxStoresPerMemsetOptSize
Likewise for functions with the OptSize attribute.
EVT getShiftAmountTy(EVT LHSTy, const DataLayout &DL) const
Returns the type for the shift amount of a shift opcode.
unsigned MaxStoresPerMemmove
Specify maximum number of store instructions per memmove call.
virtual EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, EVT VT) const
Return the ValueType of the result of SETCC operations.
virtual EVT getTypeToTransformTo(LLVMContext &Context, EVT VT) const
For types supported by the target, this is an identity function.
unsigned MaxStoresPerMemmoveOptSize
Likewise for functions with the OptSize attribute.
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
void setSupportsUnalignedAtomics(bool UnalignedSupported)
Sets whether unaligned atomic operations are supported.
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.
virtual bool shouldReduceLoadWidth(SDNode *Load, ISD::LoadExtType ExtTy, EVT NewVT) const
Return true if it is profitable to reduce a load to a smaller type.
void setTruncStoreAction(MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified truncating store does not work with the specified type and indicate what ...
void setMinCmpXchgSizeInBits(unsigned SizeInBits)
Sets the minimum cmpxchg or ll/sc size supported by the backend.
void AddPromotedToType(unsigned Opc, MVT OrigVT, MVT DestVT)
If Opc/OrigVT is specified as being promoted, the promotion code defaults to trying a larger integer/...
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...
unsigned GatherAllAliasesMaxDepth
Depth that GatherAllAliases should continue looking for chain dependencies when trying to find a more...
NegatibleCost
Enum that specifies when a float negation is beneficial.
bool allowsMemoryAccessForAlignment(LLVMContext &Context, const DataLayout &DL, EVT VT, unsigned AddrSpace=0, Align Alignment=Align(1), MachineMemOperand::Flags Flags=MachineMemOperand::MONone, unsigned *Fast=nullptr) const
This function returns true if the memory access is aligned or if the target allows this specific unal...
void setHasMultipleConditionRegisters(bool hasManyRegs=true)
Tells the code generator that the target has multiple (allocatable) condition registers that can be u...
unsigned MaxStoresPerMemcpy
Specify maximum number of store instructions per memcpy call.
void setSchedulingPreference(Sched::Preference Pref)
Specify the target scheduling preference.
void setJumpIsExpensive(bool isExpensive=true)
Tells the code generator not to expand logic operations on comparison predicates into separate sequen...
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
SDValue scalarizeVectorStore(StoreSDNode *ST, SelectionDAG &DAG) const
SDValue SimplifyMultipleUseDemandedBits(SDValue Op, const APInt &DemandedBits, const APInt &DemandedElts, SelectionDAG &DAG, unsigned Depth=0) const
More limited version of SimplifyDemandedBits that can be used to "look through" ops that don't contri...
SDValue expandUnalignedStore(StoreSDNode *ST, SelectionDAG &DAG) const
Expands an unaligned store to 2 half-size stores for integer values, and possibly more for vectors.
bool ShrinkDemandedConstant(SDValue Op, const APInt &DemandedBits, const APInt &DemandedElts, TargetLoweringOpt &TLO) const
Check to see if the specified operand of the specified instruction is a constant integer.
std::pair< SDValue, SDValue > expandUnalignedLoad(LoadSDNode *LD, SelectionDAG &DAG) const
Expands an unaligned load to 2 half-size loads for an integer, and possibly more for vectors.
virtual SDValue getNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps, bool OptForSize, NegatibleCost &Cost, unsigned Depth=0) const
Return the newly negated expression if the cost is not expensive and set the cost in Cost to indicate...
std::pair< SDValue, SDValue > scalarizeVectorLoad(LoadSDNode *LD, SelectionDAG &DAG) const
Turn load of vector type into a load of the individual elements.
bool SimplifyDemandedBits(SDValue Op, const APInt &DemandedBits, const APInt &DemandedElts, KnownBits &Known, TargetLoweringOpt &TLO, unsigned Depth=0, bool AssumeSingleUse=false) const
Look at Op.
Primary interface to the complete machine description for the target machine.
static constexpr TypeSize getFixed(ScalarTy ExactSize)
The instances of the Type class are immutable: once they are created, they are never changed.
unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
LLVM Value Representation.
StringRef getName() const
Return a constant reference to the value's name.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ CONSTANT_ADDRESS_32BIT
Address space for 32-bit constant memory.
@ REGION_ADDRESS
Address space for region memory. (GDS)
@ LOCAL_ADDRESS
Address space for local memory.
@ CONSTANT_ADDRESS
Address space for constant memory (VTX2).
@ GLOBAL_ADDRESS
Address space for global memory (RAT0, VTX0).
bool isIntrinsicAlwaysUniform(unsigned IntrID)
TargetExtType * isNamedBarrier(const GlobalVariable &GV)
@ AMDGPU_CS
Used for Mesa/AMDPAL compute shaders.
@ AMDGPU_VS
Used for Mesa vertex shaders, or AMDPAL last shader stage before rasterization (vertex shader if tess...
@ AMDGPU_KERNEL
Used for AMDGPU code object kernels.
@ AMDGPU_Gfx
Used for AMD graphics targets.
@ AMDGPU_CS_ChainPreserve
Used on AMDGPUs to give the middle-end more control over argument placement.
@ AMDGPU_HS
Used for Mesa/AMDPAL hull shaders (= tessellation control shaders).
@ AMDGPU_GS
Used for Mesa/AMDPAL geometry shaders.
@ AMDGPU_CS_Chain
Used on AMDGPUs to give the middle-end more control over argument placement.
@ AMDGPU_PS
Used for Mesa/AMDPAL pixel shaders.
@ Cold
Attempts to make code in the caller as efficient as possible under the assumption that the call is no...
@ SPIR_KERNEL
Used for SPIR kernel functions.
@ Fast
Attempts to make calls as fast as possible (e.g.
@ AMDGPU_ES
Used for AMDPAL shader stage before geometry shader if geometry is in use.
@ AMDGPU_LS
Used for AMDPAL vertex shader if tessellation is in use.
@ C
The default llvm calling convention, compatible with C.
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
@ INSERT_SUBVECTOR
INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector with VECTOR2 inserted into VECTOR1.
@ BSWAP
Byte Swap and Counting operators.
@ ATOMIC_STORE
OUTCHAIN = ATOMIC_STORE(INCHAIN, val, ptr) This corresponds to "store atomic" instruction.
@ ADDC
Carry-setting nodes for multiple precision addition and subtraction.
@ FMAD
FMAD - Perform a * b + c, while getting the same result as the separately rounded operations.
@ ADD
Simple integer binary arithmetic operators.
@ 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.
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
@ CONCAT_VECTORS
CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of vector type with the same length ...
@ FADD
Simple binary floating point operators.
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
@ FP16_TO_FP
FP16_TO_FP, FP_TO_FP16 - These operators are used to perform promotions and truncation for half-preci...
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ BUILD_PAIR
BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.
@ FLDEXP
FLDEXP - ldexp, inspired by libm (op0 * 2**op1).
@ SIGN_EXTEND
Conversion operators.
@ CTTZ_ZERO_UNDEF
Bit counting operators with an undefined result for zero inputs.
@ FNEG
Perform various unary floating-point operations inspired by libm.
@ BRIND
BRIND - Indirect branch.
@ BR_JT
BR_JT - Jumptable branch.
@ FCANONICALIZE
Returns platform specific canonical encoding of a floating point number.
@ IS_FPCLASS
Performs a check of floating point class property, defined by IEEE-754.
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
@ ATOMIC_LOAD
Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) This corresponds to "load atomic" instruction.
@ EXTRACT_ELEMENT
EXTRACT_ELEMENT - This is used to get the lower or upper (determined by a Constant,...
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
@ SHL
Shift and rotation operations.
@ VECTOR_SHUFFLE
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
@ EXTRACT_SUBVECTOR
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR.
@ FMINNUM_IEEE
FMINNUM_IEEE/FMAXNUM_IEEE - Perform floating-point minimumNumber or maximumNumber on two values,...
@ EntryToken
EntryToken - This is the marker used to indicate the start of a region.
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ CopyToReg
CopyToReg - This node has three operands: a chain, a register number to set to this value,...
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
@ FMINNUM
FMINNUM/FMAXNUM - Perform floating-point minimum or maximum on two values.
@ DYNAMIC_STACKALLOC
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary.
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
@ FP_EXTEND
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
@ UADDO_CARRY
Carry-using nodes for multiple precision addition and subtraction.
@ INLINEASM_BR
INLINEASM_BR - Branching version of inline asm. Used by asm-goto.
@ 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.
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ TRAP
TRAP - Trapping instruction.
@ INTRINSIC_WO_CHAIN
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
@ ADDE
Carry-using nodes for multiple precision addition and subtraction.
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
@ FFREXP
FFREXP - frexp, extract fractional and exponent component of a floating-point value.
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
@ ADDRSPACECAST
ADDRSPACECAST - This operator converts between pointers of different address spaces.
@ INLINEASM
INLINEASM - Represents an inline asm block.
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
bool isNormalStore(const SDNode *N)
Returns true if the specified node is a non-truncating and unindexed store.
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.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
MaybeAlign getAlign(const Function &F, unsigned Index)
ConstantFPSDNode * isConstOrConstSplatFP(SDValue N, bool AllowUndefs=false)
Returns the SDNode if it is a constant splat BuildVector or constant float.
uint64_t PowerOf2Ceil(uint64_t A)
Returns the power of two which is greater than or equal to the given value.
int countl_zero(T Val)
Count number of 0's from the most significant bit to the least stopping at the first 1.
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
bool CCAssignFn(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
CCAssignFn - This function assigns a location for Val, updating State to reflect the change.
@ Mul
Product of integers.
@ And
Bitwise or logical AND of integers.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
DWARFExpression::Operation Op
void ComputeValueVTs(const TargetLowering &TLI, const DataLayout &DL, Type *Ty, SmallVectorImpl< EVT > &ValueVTs, SmallVectorImpl< EVT > *MemVTs, SmallVectorImpl< TypeSize > *Offsets=nullptr, TypeSize StartingOffset=TypeSize::getZero())
ComputeValueVTs - Given an LLVM IR type, compute a sequence of EVTs that represent all the individual...
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
bool isOneConstant(SDValue V)
Returns true if V is a constant integer one.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
APFloat neg(APFloat X)
Returns the negated value of the argument.
unsigned Log2(Align A)
Returns the log2 of the alignment.
bool isAllOnesConstant(SDValue V)
Returns true if V is an integer constant with all bits set.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
static const fltSemantics & IEEEsingle() LLVM_READNONE
static constexpr roundingMode rmNearestTiesToEven
static const fltSemantics & IEEEdouble() LLVM_READNONE
static const fltSemantics & IEEEhalf() LLVM_READNONE
This struct is a compact representation of a valid (non-zero power of two) alignment.
MCRegister getRegister() const
unsigned getStackOffset() const
DenormalModeKind Input
Denormal treatment kind for floating point instruction inputs in the default floating-point environme...
@ PreserveSign
The sign of a flushed-to-zero number is preserved in the sign of 0.
static constexpr DenormalMode getPreserveSign()
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
EVT getPow2VectorType(LLVMContext &Context) const
Widens the length of the given vector EVT up to the nearest power of 2 and returns that type.
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
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.
EVT changeTypeToInteger() const
Return the type converted to an equivalently sized integer or vector with integer element type.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
bool isByteSized() const
Return true if the bit size is a multiple of 8.
uint64_t getScalarSizeInBits() const
EVT getHalfSizedIntegerVT(LLVMContext &Context) const
Finds the smallest simple value type that is greater than or equal to half the width of this EVT.
bool isPow2VectorType() const
Returns true if the given vector is a power of 2.
TypeSize getStoreSizeInBits() const
Return the number of bits overwritten by a store of the specified value type.
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
EVT getRoundIntegerType(LLVMContext &Context) const
Rounds the bit-width of the given integer EVT up to the nearest power of two (and at least to eight),...
bool isVector() const
Return true if this is a vector value type.
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
bool bitsGE(EVT VT) const
Return true if this has no less bits than VT.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
bool isExtended() const
Test if the given EVT is extended (as opposed to being simple).
const fltSemantics & getFltSemantics() const
Returns an APFloat semantics tag appropriate for the value type.
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
bool bitsLE(EVT VT) const
Return true if this has no more bits than VT.
bool isInteger() const
Return true if this is an integer or a vector integer type.
InputArg - This struct carries flags and type information about a single incoming (formal) argument o...
bool isNonNegative() const
Returns true if this value is known to be non-negative.
unsigned countMinTrailingZeros() const
Returns the minimum number of trailing zero bits.
bool isUnknown() const
Returns true if we don't know any bits.
KnownBits trunc(unsigned BitWidth) const
Return known bits for a truncation of the value we're tracking.
unsigned getBitWidth() const
Get the bit width of this value.
void resetAll()
Resets the known state of all bits.
unsigned countMaxActiveBits() const
Returns the maximum number of bits needed to represent all possible unsigned values with these known ...
unsigned countMinLeadingZeros() const
Returns the minimum number of leading zero bits.
APInt getMaxValue() const
Return the maximal unsigned value possible given these KnownBits.
bool isStrictlyPositive() const
Returns true if this value is known to be positive.
bool isNegative() const
Returns true if this value is known to be negative.
unsigned countMaxSignificantBits() const
Returns the maximum number of bits needed to represent all possible signed values with these known bi...
This class contains a discriminated union of information about pointers in memory operands,...
bool isDereferenceable(unsigned Size, LLVMContext &C, const DataLayout &DL) const
Return true if memory region [V, V+Offset+Size) is known to be dereferenceable.
static MachinePointerInfo getStack(MachineFunction &MF, int64_t Offset, uint8_t ID=0)
Stack pointer relative access.
MachinePointerInfo getWithOffset(int64_t O) const
These are IR-level optimization flags that may be propagated to SDNodes.
void setAllowContract(bool b)
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
DenormalMode FP32Denormals
If this is set, neither input or output denormals are flushed for most f32 instructions.
This structure contains all information that is necessary for lowering calls.
SmallVector< ISD::InputArg, 32 > Ins
bool isBeforeLegalizeOps() const
CombineLevel getDAGCombineLevel()
void AddToWorklist(SDNode *N)
bool isCalledByLegalizer() const
bool isBeforeLegalize() const
SDValue CombineTo(SDNode *N, ArrayRef< SDValue > To, bool AddTo=true)
void CommitTargetLoweringOpt(const TargetLoweringOpt &TLO)
A convenience struct that encapsulates a DAG, and two SDValues for returning information from TargetL...