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 (N->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() && Options.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 (RHS)

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 (RHS)

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 (RHS)

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 (N->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() && N->isDivergent())

4459

4462

4463 SDValue N0 = N->getOperand(0);

4464 SDValue N1 = N->getOperand(1);

4465

4466 if (isI24(N0, DAG) || isI24(N1, DAG))

4468

4471

4475}

4476

4479 EVT VT = N->getValueType(0);

4480

4483

4484

4485

4486

4487

4488

4489

4490 if (Subtarget->hasSMulHi() && N->isDivergent())

4492

4495

4496 SDValue N0 = N->getOperand(0);

4497 SDValue N1 = N->getOperand(1);

4498

4499 if (isU24(N0, DAG) || isU24(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

4820 LHS = LHS.getOperand(0);

4821

4824 else

4825 RHS = RHS.getOperand(0);

4826

4829 return SDValue();

4832 return Res;

4833 }

4836

4837

4840

4842 LHS = LHS.getOperand(0);

4844 RHS = RHS.getOperand(0);

4845 else

4847

4850 return SDValue();

4853 return Res;

4854 }

4857

4860

4861

4865

4867 LHS = LHS.getOperand(0);

4870 else

4872

4875 else

4876 RHS = RHS.getOperand(0);

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(N->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 (MRI.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 (MI)

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...