Skip to content

Commit 5db0584

Browse files
farzonlmahesh-attarde
authored andcommitted
[DirectX] Fix crash in passes when building with LLVM_ENABLE_EXPENSIVE_CHECKS (llvm#150483)
fixes llvm#148681 fixes llvm#148680 For the scalarizer pass we just need to indicate that scalarization took place, I used the logic for knowing when to eraseFromParent to indicate this. For the DXILLegalizePass the new `legalizeScalarLoadStoreOnArrays` did not use `ToRemove` which means our uses of !ToRemove.empty(); was no longer correct. This meant each legalization now needed a means of indicated if a change was maded. For DXILResourceAccess.cpp the `Changed` bool was never set to true. So removed it and replaced it with `!Resources.empty();` since we only call `replaceAccess` if we have items in Resources.
1 parent 276d88c commit 5db0584

File tree

3 files changed

+58
-46
lines changed

3 files changed

+58
-46
lines changed

llvm/lib/Target/DirectX/DXILLegalizePass.cpp

Lines changed: 54 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,19 @@
2424

2525
using namespace llvm;
2626

27-
static void legalizeFreeze(Instruction &I,
27+
static bool legalizeFreeze(Instruction &I,
2828
SmallVectorImpl<Instruction *> &ToRemove,
2929
DenseMap<Value *, Value *>) {
3030
auto *FI = dyn_cast<FreezeInst>(&I);
3131
if (!FI)
32-
return;
32+
return false;
3333

3434
FI->replaceAllUsesWith(FI->getOperand(0));
3535
ToRemove.push_back(FI);
36+
return true;
3637
}
3738

38-
static void fixI8UseChain(Instruction &I,
39+
static bool fixI8UseChain(Instruction &I,
3940
SmallVectorImpl<Instruction *> &ToRemove,
4041
DenseMap<Value *, Value *> &ReplacedValues) {
4142

@@ -74,19 +75,19 @@ static void fixI8UseChain(Instruction &I,
7475
if (Trunc->getDestTy()->isIntegerTy(8)) {
7576
ReplacedValues[Trunc] = Trunc->getOperand(0);
7677
ToRemove.push_back(Trunc);
77-
return;
78+
return true;
7879
}
7980
}
8081

8182
if (auto *Store = dyn_cast<StoreInst>(&I)) {
8283
if (!Store->getValueOperand()->getType()->isIntegerTy(8))
83-
return;
84+
return false;
8485
SmallVector<Value *> NewOperands;
8586
ProcessOperands(NewOperands);
8687
Value *NewStore = Builder.CreateStore(NewOperands[0], NewOperands[1]);
8788
ReplacedValues[Store] = NewStore;
8889
ToRemove.push_back(Store);
89-
return;
90+
return true;
9091
}
9192

9293
if (auto *Load = dyn_cast<LoadInst>(&I);
@@ -104,17 +105,17 @@ static void fixI8UseChain(Instruction &I,
104105
LoadInst *NewLoad = Builder.CreateLoad(ElementType, NewOperands[0]);
105106
ReplacedValues[Load] = NewLoad;
106107
ToRemove.push_back(Load);
107-
return;
108+
return true;
108109
}
109110

110111
if (auto *Load = dyn_cast<LoadInst>(&I);
111112
Load && isa<ConstantExpr>(Load->getPointerOperand())) {
112113
auto *CE = dyn_cast<ConstantExpr>(Load->getPointerOperand());
113114
if (!(CE->getOpcode() == Instruction::GetElementPtr))
114-
return;
115+
return false;
115116
auto *GEP = dyn_cast<GEPOperator>(CE);
116117
if (!GEP->getSourceElementType()->isIntegerTy(8))
117-
return;
118+
return false;
118119

119120
Type *ElementType = Load->getType();
120121
ConstantInt *Offset = dyn_cast<ConstantInt>(GEP->getOperand(1));
@@ -143,12 +144,12 @@ static void fixI8UseChain(Instruction &I,
143144
ReplacedValues[Load] = NewLoad;
144145
Load->replaceAllUsesWith(NewLoad);
145146
ToRemove.push_back(Load);
146-
return;
147+
return true;
147148
}
148149

149150
if (auto *BO = dyn_cast<BinaryOperator>(&I)) {
150151
if (!I.getType()->isIntegerTy(8))
151-
return;
152+
return false;
152153
SmallVector<Value *> NewOperands;
153154
ProcessOperands(NewOperands);
154155
Value *NewInst =
@@ -162,43 +163,43 @@ static void fixI8UseChain(Instruction &I,
162163
}
163164
ReplacedValues[BO] = NewInst;
164165
ToRemove.push_back(BO);
165-
return;
166+
return true;
166167
}
167168

168169
if (auto *Sel = dyn_cast<SelectInst>(&I)) {
169170
if (!I.getType()->isIntegerTy(8))
170-
return;
171+
return false;
171172
SmallVector<Value *> NewOperands;
172173
ProcessOperands(NewOperands);
173174
Value *NewInst = Builder.CreateSelect(Sel->getCondition(), NewOperands[1],
174175
NewOperands[2]);
175176
ReplacedValues[Sel] = NewInst;
176177
ToRemove.push_back(Sel);
177-
return;
178+
return true;
178179
}
179180

180181
if (auto *Cmp = dyn_cast<CmpInst>(&I)) {
181182
if (!Cmp->getOperand(0)->getType()->isIntegerTy(8))
182-
return;
183+
return false;
183184
SmallVector<Value *> NewOperands;
184185
ProcessOperands(NewOperands);
185186
Value *NewInst =
186187
Builder.CreateCmp(Cmp->getPredicate(), NewOperands[0], NewOperands[1]);
187188
Cmp->replaceAllUsesWith(NewInst);
188189
ReplacedValues[Cmp] = NewInst;
189190
ToRemove.push_back(Cmp);
190-
return;
191+
return true;
191192
}
192193

193194
if (auto *Cast = dyn_cast<CastInst>(&I)) {
194195
if (!Cast->getSrcTy()->isIntegerTy(8))
195-
return;
196+
return false;
196197

197198
ToRemove.push_back(Cast);
198199
auto *Replacement = ReplacedValues[Cast->getOperand(0)];
199200
if (Cast->getType() == Replacement->getType()) {
200201
Cast->replaceAllUsesWith(Replacement);
201-
return;
202+
return true;
202203
}
203204

204205
Value *AdjustedCast = nullptr;
@@ -213,7 +214,7 @@ static void fixI8UseChain(Instruction &I,
213214
if (auto *GEP = dyn_cast<GetElementPtrInst>(&I)) {
214215
if (!GEP->getType()->isPointerTy() ||
215216
!GEP->getSourceElementType()->isIntegerTy(8))
216-
return;
217+
return false;
217218

218219
Value *BasePtr = GEP->getPointerOperand();
219220
if (ReplacedValues.count(BasePtr))
@@ -248,15 +249,17 @@ static void fixI8UseChain(Instruction &I,
248249
ReplacedValues[GEP] = NewGEP;
249250
GEP->replaceAllUsesWith(NewGEP);
250251
ToRemove.push_back(GEP);
252+
return true;
251253
}
254+
return false;
252255
}
253256

254-
static void upcastI8AllocasAndUses(Instruction &I,
257+
static bool upcastI8AllocasAndUses(Instruction &I,
255258
SmallVectorImpl<Instruction *> &ToRemove,
256259
DenseMap<Value *, Value *> &ReplacedValues) {
257260
auto *AI = dyn_cast<AllocaInst>(&I);
258261
if (!AI || !AI->getAllocatedType()->isIntegerTy(8))
259-
return;
262+
return false;
260263

261264
Type *SmallestType = nullptr;
262265

@@ -291,16 +294,17 @@ static void upcastI8AllocasAndUses(Instruction &I,
291294
}
292295

293296
if (!SmallestType)
294-
return; // no valid casts found
297+
return false; // no valid casts found
295298

296299
// Replace alloca
297300
IRBuilder<> Builder(AI);
298301
auto *NewAlloca = Builder.CreateAlloca(SmallestType);
299302
ReplacedValues[AI] = NewAlloca;
300303
ToRemove.push_back(AI);
304+
return true;
301305
}
302306

303-
static void
307+
static bool
304308
downcastI64toI32InsertExtractElements(Instruction &I,
305309
SmallVectorImpl<Instruction *> &ToRemove,
306310
DenseMap<Value *, Value *> &) {
@@ -318,6 +322,7 @@ downcastI64toI32InsertExtractElements(Instruction &I,
318322

319323
Extract->replaceAllUsesWith(NewExtract);
320324
ToRemove.push_back(Extract);
325+
return true;
321326
}
322327
}
323328

@@ -335,8 +340,10 @@ downcastI64toI32InsertExtractElements(Instruction &I,
335340

336341
Insert->replaceAllUsesWith(Insert32Index);
337342
ToRemove.push_back(Insert);
343+
return true;
338344
}
339345
}
346+
return false;
340347
}
341348

342349
static void emitMemcpyExpansion(IRBuilder<> &Builder, Value *Dst, Value *Src,
@@ -453,17 +460,17 @@ static void emitMemsetExpansion(IRBuilder<> &Builder, Value *Dst, Value *Val,
453460
// Expands the instruction `I` into corresponding loads and stores if it is a
454461
// memcpy call. In that case, the call instruction is added to the `ToRemove`
455462
// vector. `ReplacedValues` is unused.
456-
static void legalizeMemCpy(Instruction &I,
463+
static bool legalizeMemCpy(Instruction &I,
457464
SmallVectorImpl<Instruction *> &ToRemove,
458465
DenseMap<Value *, Value *> &ReplacedValues) {
459466

460467
CallInst *CI = dyn_cast<CallInst>(&I);
461468
if (!CI)
462-
return;
469+
return false;
463470

464471
Intrinsic::ID ID = CI->getIntrinsicID();
465472
if (ID != Intrinsic::memcpy)
466-
return;
473+
return false;
467474

468475
IRBuilder<> Builder(&I);
469476
Value *Dst = CI->getArgOperand(0);
@@ -476,19 +483,20 @@ static void legalizeMemCpy(Instruction &I,
476483
assert(IsVolatile->getZExtValue() == 0 && "Expected IsVolatile to be false");
477484
emitMemcpyExpansion(Builder, Dst, Src, Length);
478485
ToRemove.push_back(CI);
486+
return true;
479487
}
480488

481-
static void legalizeMemSet(Instruction &I,
489+
static bool legalizeMemSet(Instruction &I,
482490
SmallVectorImpl<Instruction *> &ToRemove,
483491
DenseMap<Value *, Value *> &ReplacedValues) {
484492

485493
CallInst *CI = dyn_cast<CallInst>(&I);
486494
if (!CI)
487-
return;
495+
return false;
488496

489497
Intrinsic::ID ID = CI->getIntrinsicID();
490498
if (ID != Intrinsic::memset)
491-
return;
499+
return false;
492500

493501
IRBuilder<> Builder(&I);
494502
Value *Dst = CI->getArgOperand(0);
@@ -497,23 +505,25 @@ static void legalizeMemSet(Instruction &I,
497505
assert(Size && "Expected Size to be a ConstantInt");
498506
emitMemsetExpansion(Builder, Dst, Val, Size, ReplacedValues);
499507
ToRemove.push_back(CI);
508+
return true;
500509
}
501510

502-
static void updateFnegToFsub(Instruction &I,
511+
static bool updateFnegToFsub(Instruction &I,
503512
SmallVectorImpl<Instruction *> &ToRemove,
504513
DenseMap<Value *, Value *> &) {
505514
const Intrinsic::ID ID = I.getOpcode();
506515
if (ID != Instruction::FNeg)
507-
return;
516+
return false;
508517

509518
IRBuilder<> Builder(&I);
510519
Value *In = I.getOperand(0);
511520
Value *Zero = ConstantFP::get(In->getType(), -0.0);
512521
I.replaceAllUsesWith(Builder.CreateFSub(Zero, In));
513522
ToRemove.push_back(&I);
523+
return true;
514524
}
515525

516-
static void
526+
static bool
517527
legalizeGetHighLowi64Bytes(Instruction &I,
518528
SmallVectorImpl<Instruction *> &ToRemove,
519529
DenseMap<Value *, Value *> &ReplacedValues) {
@@ -523,13 +533,13 @@ legalizeGetHighLowi64Bytes(Instruction &I,
523533
BitCast->getSrcTy()->isIntegerTy(64)) {
524534
ToRemove.push_back(BitCast);
525535
ReplacedValues[BitCast] = BitCast->getOperand(0);
526-
return;
536+
return true;
527537
}
528538
}
529539

530540
if (auto *Extract = dyn_cast<ExtractElementInst>(&I)) {
531541
if (!dyn_cast<BitCastInst>(Extract->getVectorOperand()))
532-
return;
542+
return false;
533543
auto *VecTy = dyn_cast<FixedVectorType>(Extract->getVectorOperandType());
534544
if (VecTy && VecTy->getElementType()->isIntegerTy(32) &&
535545
VecTy->getNumElements() == 2) {
@@ -557,12 +567,14 @@ legalizeGetHighLowi64Bytes(Instruction &I,
557567
}
558568
ToRemove.push_back(Extract);
559569
Extract->replaceAllUsesWith(ReplacedValues[Extract]);
570+
return true;
560571
}
561572
}
562573
}
574+
return false;
563575
}
564576

565-
static void
577+
static bool
566578
legalizeScalarLoadStoreOnArrays(Instruction &I,
567579
SmallVectorImpl<Instruction *> &ToRemove,
568580
DenseMap<Value *, Value *> &) {
@@ -579,25 +591,25 @@ legalizeScalarLoadStoreOnArrays(Instruction &I,
579591
PtrOpIndex = SI->getPointerOperandIndex();
580592
LoadStoreTy = SI->getValueOperand()->getType();
581593
} else
582-
return;
594+
return false;
583595

584596
// If the load/store is not of a single-value type (i.e., scalar or vector)
585597
// then we do not modify it. It shouldn't be a vector either because the
586598
// dxil-data-scalarization pass is expected to run before this, but it's not
587599
// incorrect to apply this transformation to vector load/stores.
588600
if (!LoadStoreTy->isSingleValueType())
589-
return;
601+
return false;
590602

591603
Type *ArrayTy;
592604
if (auto *GlobalVarPtrOp = dyn_cast<GlobalVariable>(PtrOp))
593605
ArrayTy = GlobalVarPtrOp->getValueType();
594606
else if (auto *AllocaPtrOp = dyn_cast<AllocaInst>(PtrOp))
595607
ArrayTy = AllocaPtrOp->getAllocatedType();
596608
else
597-
return;
609+
return false;
598610

599611
if (!isa<ArrayType>(ArrayTy))
600-
return;
612+
return false;
601613

602614
assert(ArrayTy->getArrayElementType() == LoadStoreTy &&
603615
"Expected array element type to be the same as to the scalar load or "
@@ -607,6 +619,7 @@ legalizeScalarLoadStoreOnArrays(Instruction &I,
607619
Value *GEP = GetElementPtrInst::Create(
608620
ArrayTy, PtrOp, {Zero, Zero}, GEPNoWrapFlags::all(), "", I.getIterator());
609621
I.setOperand(PtrOpIndex, GEP);
622+
return true;
610623
}
611624

612625
namespace {
@@ -624,13 +637,11 @@ class DXILLegalizationPipeline {
624637
ReplacedValues.clear();
625638
for (auto &I : instructions(F)) {
626639
for (auto &LegalizationFn : LegalizationPipeline[Stage])
627-
LegalizationFn(I, ToRemove, ReplacedValues);
640+
MadeChange |= LegalizationFn(I, ToRemove, ReplacedValues);
628641
}
629642

630643
for (auto *Inst : reverse(ToRemove))
631644
Inst->eraseFromParent();
632-
633-
MadeChange |= !ToRemove.empty();
634645
}
635646
return MadeChange;
636647
}
@@ -639,7 +650,7 @@ class DXILLegalizationPipeline {
639650
enum LegalizationStage { Stage1 = 0, Stage2 = 1, NumStages };
640651

641652
using LegalizationFnTy =
642-
std::function<void(Instruction &, SmallVectorImpl<Instruction *> &,
653+
std::function<bool(Instruction &, SmallVectorImpl<Instruction *> &,
643654
DenseMap<Value *, Value *> &)>;
644655

645656
SmallVector<LegalizationFnTy> LegalizationPipeline[NumStages];

llvm/lib/Target/DirectX/DXILResourceAccess.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,6 @@ static void replaceAccess(IntrinsicInst *II, dxil::ResourceTypeInfo &RTI) {
241241
}
242242

243243
static bool transformResourcePointers(Function &F, DXILResourceTypeMap &DRTM) {
244-
bool Changed = false;
245244
SmallVector<std::pair<IntrinsicInst *, dxil::ResourceTypeInfo>> Resources;
246245
for (BasicBlock &BB : F)
247246
for (Instruction &I : BB)
@@ -254,7 +253,7 @@ static bool transformResourcePointers(Function &F, DXILResourceTypeMap &DRTM) {
254253
for (auto &[II, RI] : Resources)
255254
replaceAccess(II, RI);
256255

257-
return Changed;
256+
return !Resources.empty();
258257
}
259258

260259
PreservedAnalyses DXILResourceAccess::run(Function &F,

llvm/lib/Transforms/Scalar/Scalarizer.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -458,8 +458,10 @@ bool ScalarizerVisitor::visit(Function &F) {
458458
Instruction *I = &*II;
459459
bool Done = InstVisitor::visit(I);
460460
++II;
461-
if (Done && I->getType()->isVoidTy())
461+
if (Done && I->getType()->isVoidTy()) {
462462
I->eraseFromParent();
463+
Scalarized = true;
464+
}
463465
}
464466
}
465467
return finish();

0 commit comments

Comments
 (0)