LLVM: lib/Transforms/Scalar/ScalarizeMaskedMemIntrin.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

38#include

39#include

40

41using namespace llvm;

42

43#define DEBUG_TYPE "scalarize-masked-mem-intrin"

44

45namespace {

46

47class ScalarizeMaskedMemIntrinLegacyPass : public FunctionPass {

48public:

49 static char ID;

50

51 explicit ScalarizeMaskedMemIntrinLegacyPass() : FunctionPass(ID) {

54 }

55

57

59 return "Scalarize Masked Memory Intrinsics";

60 }

61

65 }

66};

67

68}

69

75 const DataLayout &DL, bool HasBranchDivergence,

77

78char ScalarizeMaskedMemIntrinLegacyPass::ID = 0;

79

81 "Scalarize unsupported masked memory intrinsics", false,

82 false)

88

90 return new ScalarizeMaskedMemIntrinLegacyPass();

91}

92

94 Constant *C = dyn_cast(Mask);

95 if (C)

96 return false;

97

98 unsigned NumElts = cast(Mask->getType())->getNumElements();

99 for (unsigned i = 0; i != NumElts; ++i) {

100 Constant *CElt = C->getAggregateElement(i);

101 if (!CElt || !isa(CElt))

102 return false;

103 }

104

105 return true;

106}

107

109 unsigned Idx) {

110 return DL.isBigEndian() ? VectorWidth - 1 - Idx : Idx;

111}

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

147 bool &ModifiedDT) {

152

153 const Align AlignVal = cast(Alignment)->getAlignValue();

155

156 Type *EltTy = VecType->getElementType();

157

161

164

165

166 if (isa(Mask) && cast(Mask)->isAllOnesValue()) {

172 return;

173 }

174

175

176 const Align AdjustedAlignVal =

178 unsigned VectorWidth = cast(VecType)->getNumElements();

179

180

181 Value *VResult = Src0;

182

184 for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) {

185 if (cast(Mask)->getAggregateElement(Idx)->isNullValue())

186 continue;

190 }

193 return;

194 }

195

196

197

198

201 Mask->getName() + ".first");

204 nullptr, DTU);

205

207 CondBlock->setName("cond.load");

210 CI->getName() + ".cond.load");

211 Load->copyMetadata(*CI);

212

215 PHINode *Phi = Builder.CreatePHI(VecType, 2);

216 Phi->addIncoming(Load, CondBlock);

217 Phi->addIncoming(Src0, IfBlock);

218 Phi->takeName(CI);

219

222 ModifiedDT = true;

223 return;

224 }

225

226

227

228 Value *SclrMask = nullptr;

229 if (VectorWidth != 1 && !HasBranchDivergence) {

230 Type *SclrMaskTy = Builder.getIntNTy(VectorWidth);

231 SclrMask = Builder.CreateBitCast(Mask, SclrMaskTy, "scalar_mask");

232 }

233

234 for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) {

235

236

237

238

239

240

241

242

243

244 Value *Predicate;

245 if (SclrMask != nullptr) {

249 Builder.getIntN(VectorWidth, 0));

250 } else {

252 }

253

254

255

256

257

258

259

262 nullptr, DTU);

263

265 CondBlock->setName("cond.load");

266

271

272

274 NewIfBlock->setName("else");

276 IfBlock = NewIfBlock;

277

278

280 PHINode *Phi = Builder.CreatePHI(VecType, 2, "res.phi.else");

281 Phi->addIncoming(NewVResult, CondBlock);

282 Phi->addIncoming(VResult, PrevIfBlock);

283 VResult = Phi;

284 }

285

288

289 ModifiedDT = true;

290}

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

320 bool &ModifiedDT) {

325

326 const Align AlignVal = cast(Alignment)->getAlignValue();

327 auto *VecType = cast(Src->getType());

328

329 Type *EltTy = VecType->getElementType();

330

335

336

337 if (isa(Mask) && cast(Mask)->isAllOnesValue()) {

339 Store->takeName(CI);

340 Store->copyMetadata(*CI);

342 return;

343 }

344

345

346 const Align AdjustedAlignVal =

348 unsigned VectorWidth = cast(VecType)->getNumElements();

349

351 for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) {

352 if (cast(Mask)->getAggregateElement(Idx)->isNullValue())

353 continue;

357 }

359 return;

360 }

361

362

363

364

367 Mask->getName() + ".first");

370 nullptr, DTU);

372 CondBlock->setName("cond.store");

374

376 Store->takeName(CI);

377 Store->copyMetadata(*CI);

378

380 ModifiedDT = true;

381 return;

382 }

383

384

385

386

387 Value *SclrMask = nullptr;

388 if (VectorWidth != 1 && !HasBranchDivergence) {

389 Type *SclrMaskTy = Builder.getIntNTy(VectorWidth);

390 SclrMask = Builder.CreateBitCast(Mask, SclrMaskTy, "scalar_mask");

391 }

392

393 for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) {

394

395

396

397

398

399

400

401

402

403 Value *Predicate;

404 if (SclrMask != nullptr) {

408 Builder.getIntN(VectorWidth, 0));

409 } else {

411 }

412

413

414

415

416

417

418

421 nullptr, DTU);

422

424 CondBlock->setName("cond.store");

425

430

431

433 NewIfBlock->setName("else");

434

436 }

438

439 ModifiedDT = true;

440}

441

442

443

444

445

446

447

448

449

450

451

452

453

454

455

456

457

458

459

460

461

462

463

464

465

466

467

468

469

470

472 bool HasBranchDivergence, CallInst *CI,

478

479 auto *VecType = cast(CI->getType());

480 Type *EltTy = VecType->getElementType();

481

486 MaybeAlign AlignVal = cast(Alignment)->getMaybeAlignValue();

487

489

490

491 Value *VResult = Src0;

492 unsigned VectorWidth = VecType->getNumElements();

493

494

496 for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) {

497 if (cast(Mask)->getAggregateElement(Idx)->isNullValue())

498 continue;

502 VResult =

504 }

507 return;

508 }

509

510

511

512

513 Value *SclrMask = nullptr;

514 if (VectorWidth != 1 && !HasBranchDivergence) {

515 Type *SclrMaskTy = Builder.getIntNTy(VectorWidth);

516 SclrMask = Builder.CreateBitCast(Mask, SclrMaskTy, "scalar_mask");

517 }

518

519 for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) {

520

521

522

523

524

525

526

527

528

529

530 Value *Predicate;

531 if (SclrMask != nullptr) {

535 Builder.getIntN(VectorWidth, 0));

536 } else {

538 }

539

540

541

542

543

544

545

548 nullptr, DTU);

549

551 CondBlock->setName("cond.load");

552

557 Value *NewVResult =

559

560

562 NewIfBlock->setName("else");

564 IfBlock = NewIfBlock;

565

566

568 PHINode *Phi = Builder.CreatePHI(VecType, 2, "res.phi.else");

569 Phi->addIncoming(NewVResult, CondBlock);

570 Phi->addIncoming(VResult, PrevIfBlock);

571 VResult = Phi;

572 }

573

576

577 ModifiedDT = true;

578}

579

580

581

582

583

584

585

586

587

588

589

590

591

592

593

594

595

596

597

598

599

600

601

602

603

604

605

607 bool HasBranchDivergence, CallInst *CI,

613

614 auto *SrcFVTy = cast(Src->getType());

615

617 isa(Ptrs->getType()) &&

618 isa(cast(Ptrs->getType())->getElementType()) &&

619 "Vector of pointers is expected in masked scatter intrinsic");

620

625

626 MaybeAlign AlignVal = cast(Alignment)->getMaybeAlignValue();

627 unsigned VectorWidth = SrcFVTy->getNumElements();

628

629

631 for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) {

632 if (cast(Mask)->getAggregateElement(Idx)->isNullValue())

633 continue;

638 }

640 return;

641 }

642

643

644

645 Value *SclrMask = nullptr;

646 if (VectorWidth != 1 && !HasBranchDivergence) {

647 Type *SclrMaskTy = Builder.getIntNTy(VectorWidth);

648 SclrMask = Builder.CreateBitCast(Mask, SclrMaskTy, "scalar_mask");

649 }

650

651 for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) {

652

653

654

655

656

657

658

659

660

661 Value *Predicate;

662 if (SclrMask != nullptr) {

666 Builder.getIntN(VectorWidth, 0));

667 } else {

669 }

670

671

672

673

674

675

676

679 nullptr, DTU);

680

682 CondBlock->setName("cond.store");

683

688

689

691 NewIfBlock->setName("else");

692

694 }

696

697 ModifiedDT = true;

698}

699

701 bool HasBranchDivergence, CallInst *CI,

707

708 auto *VecType = cast(CI->getType());

709

710 Type *EltTy = VecType->getElementType();

711

715

718

719 unsigned VectorWidth = VecType->getNumElements();

720

721

722 Value *VResult = PassThru;

723

724

725 const Align AdjustedAlignment =

727

728

729

730

732 unsigned MemIndex = 0;

735 for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) {

736 Value *InsertElt;

737 if (cast(Mask)->getAggregateElement(Idx)->isNullValue()) {

739 ShuffleMask[Idx] = Idx + VectorWidth;

740 } else {

743 InsertElt = Builder.CreateAlignedLoad(EltTy, NewPtr, AdjustedAlignment,

745 ShuffleMask[Idx] = Idx;

746 ++MemIndex;

747 }

750 }

754 return;

755 }

756

757

758

759

760 Value *SclrMask = nullptr;

761 if (VectorWidth != 1 && !HasBranchDivergence) {

762 Type *SclrMaskTy = Builder.getIntNTy(VectorWidth);

763 SclrMask = Builder.CreateBitCast(Mask, SclrMaskTy, "scalar_mask");

764 }

765

766 for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) {

767

768

769

770

771

772

773

774

775

776

777 Value *Predicate;

778 if (SclrMask != nullptr) {

782 Builder.getIntN(VectorWidth, 0));

783 } else {

785 }

786

787

788

789

790

791

792

795 nullptr, DTU);

796

798 CondBlock->setName("cond.load");

799

803

804

806 if ((Idx + 1) != VectorWidth)

808

809

811 NewIfBlock->setName("else");

813 IfBlock = NewIfBlock;

814

815

817 PHINode *ResultPhi = Builder.CreatePHI(VecType, 2, "res.phi.else");

818 ResultPhi->addIncoming(NewVResult, CondBlock);

819 ResultPhi->addIncoming(VResult, PrevIfBlock);

820 VResult = ResultPhi;

821

822

823 if ((Idx + 1) != VectorWidth) {

827 Ptr = PtrPhi;

828 }

829 }

830

833

834 ModifiedDT = true;

835}

836

838 bool HasBranchDivergence, CallInst *CI,

840 bool &ModifiedDT) {

845

846 auto *VecType = cast(Src->getType());

847

851

854

855 Type *EltTy = VecType->getElementType();

856

857

858 const Align AdjustedAlignment =

860

861 unsigned VectorWidth = VecType->getNumElements();

862

863

865 unsigned MemIndex = 0;

866 for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) {

867 if (cast(Mask)->getAggregateElement(Idx)->isNullValue())

868 continue;

873 ++MemIndex;

874 }

876 return;

877 }

878

879

880

881

882 Value *SclrMask = nullptr;

883 if (VectorWidth != 1 && !HasBranchDivergence) {

884 Type *SclrMaskTy = Builder.getIntNTy(VectorWidth);

885 SclrMask = Builder.CreateBitCast(Mask, SclrMaskTy, "scalar_mask");

886 }

887

888 for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) {

889

890

891

892

893

894

895

896

897 Value *Predicate;

898 if (SclrMask != nullptr) {

902 Builder.getIntN(VectorWidth, 0));

903 } else {

905 }

906

907

908

909

910

911

912

915 nullptr, DTU);

916

918 CondBlock->setName("cond.store");

919

923

924

926 if ((Idx + 1) != VectorWidth)

928

929

931 NewIfBlock->setName("else");

933 IfBlock = NewIfBlock;

934

936

937

938 if ((Idx + 1) != VectorWidth) {

942 Ptr = PtrPhi;

943 }

944 }

946

947 ModifiedDT = true;

948}

949

952 bool &ModifiedDT) {

953

954

959

960 auto *AddrType = cast(Ptrs->getType());

962

966

968

969

970 unsigned VectorWidth = AddrType->getNumElements();

971

972

974 for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) {

975 if (cast(Mask)->getAggregateElement(Idx)->isNullValue())

976 continue;

981 }

983 return;

984 }

985

986 for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) {

987 Value *Predicate =

989

992 nullptr, DTU);

993

995 CondBlock->setName("cond.histogram.update");

996

1002

1003

1005 NewIfBlock->setName("else");

1007 }

1008

1010 ModifiedDT = true;

1011}

1012

1015 std::optional DTU;

1016 if (DT)

1017 DTU.emplace(DT, DomTreeUpdater::UpdateStrategy::Lazy);

1018

1019 bool EverMadeChange = false;

1020 bool MadeChange = true;

1021 auto &DL = F.getDataLayout();

1023 while (MadeChange) {

1024 MadeChange = false;

1026 bool ModifiedDTOnIteration = false;

1028 HasBranchDivergence, DTU ? &*DTU : nullptr);

1029

1030

1031 if (ModifiedDTOnIteration)

1032 break;

1033 }

1034

1035 EverMadeChange |= MadeChange;

1036 }

1037 return EverMadeChange;

1038}

1039

1040bool ScalarizeMaskedMemIntrinLegacyPass::runOnFunction(Function &F) {

1041 auto &TTI = getAnalysis().getTTI(F);

1043 if (auto *DTWP = getAnalysisIfAvailable())

1044 DT = &DTWP->getDomTree();

1046}

1047

1057 return PA;

1058}

1059

1063 bool MadeChange = false;

1064

1066 while (CurInstIterator != BB.end()) {

1067 if (CallInst *CI = dyn_cast(&*CurInstIterator++))

1068 MadeChange |=

1070 if (ModifiedDT)

1071 return true;

1072 }

1073

1074 return MadeChange;

1075}

1076

1079 const DataLayout &DL, bool HasBranchDivergence,

1082 if (II) {

1083

1084 if (isa(II->getType()) ||

1086 [](Value *V) { return isa(V->getType()); }))

1087 return false;

1088 switch (II->getIntrinsicID()) {

1089 default:

1090 break;

1091 case Intrinsic::experimental_vector_histogram_add:

1094 return false;

1096 return true;

1097 case Intrinsic::masked_load:

1098

1101 cast(CI->getArgOperand(1))->getAlignValue()))

1102 return false;

1104 return true;

1105 case Intrinsic::masked_store:

1108 cast(CI->getArgOperand(2))->getAlignValue()))

1109 return false;

1111 return true;

1112 case Intrinsic::masked_gather: {

1114 cast(CI->getArgOperand(1))->getMaybeAlignValue();

1116 Align Alignment = DL.getValueOrABITypeAlignment(MA,

1120 return false;

1122 return true;

1123 }

1124 case Intrinsic::masked_scatter: {

1126 cast(CI->getArgOperand(2))->getMaybeAlignValue();

1128 Align Alignment = DL.getValueOrABITypeAlignment(MA,

1132 Alignment))

1133 return false;

1135 return true;

1136 }

1137 case Intrinsic::masked_expandload:

1141 return false;

1143 return true;

1144 case Intrinsic::masked_compressstore:

1148 return false;

1150 ModifiedDT);

1151 return true;

1152 }

1153 }

1154

1155 return false;

1156}

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

static Error unsupported(const char *Str, const Triple &T)

This file contains the declarations for the subclasses of Constant, which represent the different fla...

Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx

static bool runImpl(Function &F, const TargetLowering &TLI)

uint64_t IntrinsicInst * II

#define INITIALIZE_PASS_DEPENDENCY(depName)

#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)

#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)

assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())

static void scalarizeMaskedExpandLoad(const DataLayout &DL, bool HasBranchDivergence, CallInst *CI, DomTreeUpdater *DTU, bool &ModifiedDT)

static void scalarizeMaskedVectorHistogram(const DataLayout &DL, CallInst *CI, DomTreeUpdater *DTU, bool &ModifiedDT)

static bool optimizeBlock(BasicBlock &BB, bool &ModifiedDT, const TargetTransformInfo &TTI, const DataLayout &DL, bool HasBranchDivergence, DomTreeUpdater *DTU)

static void scalarizeMaskedScatter(const DataLayout &DL, bool HasBranchDivergence, CallInst *CI, DomTreeUpdater *DTU, bool &ModifiedDT)

static unsigned adjustForEndian(const DataLayout &DL, unsigned VectorWidth, unsigned Idx)

static bool optimizeCallInst(CallInst *CI, bool &ModifiedDT, const TargetTransformInfo &TTI, const DataLayout &DL, bool HasBranchDivergence, DomTreeUpdater *DTU)

static void scalarizeMaskedStore(const DataLayout &DL, bool HasBranchDivergence, CallInst *CI, DomTreeUpdater *DTU, bool &ModifiedDT)

static void scalarizeMaskedCompressStore(const DataLayout &DL, bool HasBranchDivergence, CallInst *CI, DomTreeUpdater *DTU, bool &ModifiedDT)

static void scalarizeMaskedGather(const DataLayout &DL, bool HasBranchDivergence, CallInst *CI, DomTreeUpdater *DTU, bool &ModifiedDT)

static bool runImpl(Function &F, const TargetTransformInfo &TTI, DominatorTree *DT)

static bool isConstantIntVector(Value *Mask)

Scalarize unsupported masked memory intrinsics

static void scalarizeMaskedLoad(const DataLayout &DL, bool HasBranchDivergence, CallInst *CI, DomTreeUpdater *DTU, bool &ModifiedDT)

This pass exposes codegen information to IR-level passes.

static APInt getOneBitSet(unsigned numBits, unsigned BitNo)

Return an APInt with exactly one bit set in the result.

A container for analyses that lazily runs them and caches their results.

PassT::Result * getCachedResult(IRUnitT &IR) const

Get the cached result of an analysis pass for a given IR unit.

PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)

Get the result of an analysis pass for a given IR unit.

Represent the analysis usage information of a pass.

AnalysisUsage & addRequired()

AnalysisUsage & addPreserved()

Add the specified Pass class to the set of analyses preserved by this pass.

AttributeSet getParamAttrs(unsigned ArgNo) const

The attributes for the argument or parameter at the given index are returned.

MaybeAlign getAlignment() const

LLVM Basic Block Representation.

iterator begin()

Instruction iterator methods.

InstListType::iterator iterator

Instruction iterators...

const Instruction * getTerminator() const LLVM_READONLY

Returns the terminator instruction if the block is well formed or null if the block is not well forme...

MaybeAlign getParamAlign(unsigned ArgNo) const

Extract the alignment for a call or parameter (0=unknown).

Value * getArgOperand(unsigned i) const

AttributeList getAttributes() const

Return the attributes for this call.

This class represents a function call, abstracting a target machine's calling convention.

This is an important base class in LLVM.

A parsed version of the target data layout string in and methods for querying it.

Analysis pass which computes a DominatorTree.

Legacy analysis pass which computes a DominatorTree.

Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.

FunctionPass class - This class is used to implement most global optimizations.

virtual bool runOnFunction(Function &F)=0

runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass.

Value * CreateInsertElement(Type *VecTy, Value *NewElt, Value *Idx, const Twine &Name="")

Value * CreateExtractElement(Value *Vec, Value *Idx, const Twine &Name="")

IntegerType * getIntNTy(unsigned N)

Fetch the type representing an N-bit integer.

LoadInst * CreateAlignedLoad(Type *Ty, Value *Ptr, MaybeAlign Align, const char *Name)

Value * CreateConstInBoundsGEP1_32(Type *Ty, Value *Ptr, unsigned Idx0, const Twine &Name="")

void SetCurrentDebugLocation(DebugLoc L)

Set location information used by debugging information.

Value * CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name="")

PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")

Value * CreateBitCast(Value *V, Type *DestTy, const Twine &Name="")

ConstantInt * getIntN(unsigned N, uint64_t C)

Get a constant N-bit value, zero extended or truncated from a 64-bit value.

LoadInst * CreateLoad(Type *Ty, Value *Ptr, const char *Name)

Provided to resolve 'CreateLoad(Ty, Ptr, "...")' correctly, instead of converting the string to 'bool...

Value * CreateShuffleVector(Value *V1, Value *V2, Value *Mask, const Twine &Name="")

Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")

StoreInst * CreateStore(Value *Val, Value *Ptr, bool isVolatile=false)

Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)

void SetInsertPoint(BasicBlock *TheBB)

This specifies that created instructions should be appended to the end of the specified block.

StoreInst * CreateAlignedStore(Value *Val, Value *Ptr, MaybeAlign Align, bool isVolatile=false)

ConstantInt * getInt(const APInt &AI)

Get a constant integer value.

This provides a uniform API for creating instructions and inserting them into a basic block: either a...

const DebugLoc & getDebugLoc() const

Return the debug location for this node as a DebugLoc.

InstListType::iterator eraseFromParent()

This method unlinks 'this' from the containing basic block and deletes it.

BasicBlock * getSuccessor(unsigned Idx) const LLVM_READONLY

Return the specified successor. This instruction must be a terminator.

void copyMetadata(const Instruction &SrcInst, ArrayRef< unsigned > WL=ArrayRef< unsigned >())

Copy metadata from SrcInst to this instruction.

A wrapper class for inspecting calls to intrinsic functions.

An instruction for reading from memory.

void addIncoming(Value *V, BasicBlock *BB)

Add an incoming value to the end of the PHI list.

static PassRegistry * getPassRegistry()

getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...

virtual void getAnalysisUsage(AnalysisUsage &) const

getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...

virtual StringRef getPassName() const

getPassName - Return a nice clean name for a pass.

static PoisonValue * get(Type *T)

Static factory methods - Return an 'poison' object of the specified type.

A set of analyses that are preserved following a run of a transformation pass.

static PreservedAnalyses all()

Construct a special preserved set that preserves all passes.

void preserve()

Mark an analysis as preserved.

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

An instruction for storing to memory.

StringRef - Represent a constant reference to a string, i.e.

Analysis pass providing the TargetTransformInfo.

Wrapper pass for TargetTransformInfo.

This pass provides access to the codegen interfaces that are needed for IR-level transformations.

bool isLegalMaskedScatter(Type *DataType, Align Alignment) const

Return true if the target supports masked scatter.

bool isLegalMaskedExpandLoad(Type *DataType, Align Alignment) const

Return true if the target supports masked expand load.

bool hasBranchDivergence(const Function *F=nullptr) const

Return true if branch divergence exists.

bool isLegalMaskedGather(Type *DataType, Align Alignment) const

Return true if the target supports masked gather.

bool forceScalarizeMaskedGather(VectorType *Type, Align Alignment) const

Return true if the target forces scalarizing of llvm.masked.gather intrinsics.

bool isLegalMaskedCompressStore(Type *DataType, Align Alignment) const

Return true if the target supports masked compress store.

bool isLegalMaskedStore(Type *DataType, Align Alignment) const

Return true if the target supports masked store.

bool isLegalMaskedVectorHistogram(Type *AddrType, Type *DataType) const

bool forceScalarizeMaskedScatter(VectorType *Type, Align Alignment) const

Return true if the target forces scalarizing of llvm.masked.scatter intrinsics.

bool isLegalMaskedLoad(Type *DataType, Align Alignment) const

Return true if the target supports masked load.

Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...

The instances of the Type class are immutable: once they are created, they are never changed.

TypeSize getPrimitiveSizeInBits() const LLVM_READONLY

Return the basic size of this type if it is a primitive type.

bool isVoidTy() const

Return true if this is 'void'.

Type * getScalarType() const

If this is a vector type, return the element type, otherwise return 'this'.

LLVM Value Representation.

Type * getType() const

All values are typed, get the type of this value.

void setName(const Twine &Name)

Change the name of the value.

void replaceAllUsesWith(Value *V)

Change all uses of this to point to a new Value.

LLVMContext & getContext() const

All values hold a context through their type.

StringRef getName() const

Return a constant reference to the value's name.

void takeName(Value *V)

Transfer the name from V to this value.

const ParentTy * getParent() const

@ C

The default llvm calling convention, compatible with C.

unsigned ID

LLVM IR allows to use arbitrary numbers as calling convention identifiers.

This is an optimization pass for GlobalISel generic memory operations.

iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)

Make a range that does early increment to allow mutation of the underlying range without disrupting i...

FunctionPass * createScalarizeMaskedMemIntrinLegacyPass()

bool any_of(R &&range, UnaryPredicate P)

Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.

bool isSplatValue(const Value *V, int Index=-1, unsigned Depth=0)

Return true if each element of the vector value V is poisoned or equal to every other non-poisoned el...

void initializeScalarizeMaskedMemIntrinLegacyPassPass(PassRegistry &)

constexpr int PoisonMaskElem

Align commonAlignment(Align A, uint64_t Offset)

Returns the alignment that satisfies both alignments.

Instruction * SplitBlockAndInsertIfThen(Value *Cond, BasicBlock::iterator SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, BasicBlock *ThenBlock=nullptr)

Split the containing block at the specified instruction - everything before SplitBefore stays in the ...

This struct is a compact representation of a valid (non-zero power of two) alignment.

This struct is a compact representation of a valid (power of two) or undefined (0) alignment.

Align valueOrOne() const

For convenience, returns a valid alignment or 1 if undefined.

PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)