@@ -108,6 +108,55 @@ Value *RandomIRBuilder::findOrCreateSource(BasicBlock &BB,
108
108
return findOrCreateSource (BB, Insts, {}, anyType ());
109
109
}
110
110
111
+ // Adapts the current pointer for a legal mem operation on the target arch.
112
+ static Value *buildTargetLegalPtr (Module *M, Value *Ptr, InsertPosition IP,
113
+ const Twine &Name,
114
+ SmallVector<Instruction *> *NewInsts) {
115
+ if (M && M->getTargetTriple ().isAMDGCN ()) {
116
+ // Check if we should perform an address space cast
117
+ PointerType *pointerType = dyn_cast<PointerType>(Ptr->getType ());
118
+ if (pointerType && pointerType->getAddressSpace () == 8 ) {
119
+ // Perform address space cast from address space 8 to address space 7
120
+ auto NewPtr = new AddrSpaceCastInst (
121
+ Ptr, PointerType::get (M->getContext (), 7 ), Name + " .ASC" , IP);
122
+ if (NewInsts)
123
+ NewInsts->push_back (NewPtr);
124
+ return NewPtr;
125
+ }
126
+ }
127
+
128
+ return Ptr;
129
+ }
130
+
131
+ // Stores a value to memory, considering the target triple's restrictions.
132
+ static Instruction *buildTargetLegalStore (Value *Val, Value *Ptr,
133
+ InsertPosition IP, Module *M) {
134
+ Value *StorePtr = buildTargetLegalPtr (M, Ptr, IP, " " , nullptr );
135
+ Instruction *Store = new StoreInst (Val, StorePtr, IP);
136
+ return Store;
137
+ }
138
+
139
+ // Loads a value from memory, considering the target triple's restrictions.
140
+ static std::pair<Instruction *, SmallVector<Instruction *>>
141
+ buildTargetLegalLoad (Type *AccessTy, Value *Ptr, InsertPosition IP, Module *M,
142
+ const Twine &LoadName) {
143
+ SmallVector<Instruction *> NewInsts;
144
+
145
+ Value *LoadPtr = buildTargetLegalPtr (M, Ptr, IP, LoadName, &NewInsts);
146
+
147
+ Instruction *Load = new LoadInst (AccessTy, LoadPtr, LoadName, IP);
148
+ NewInsts.push_back (Load);
149
+
150
+ return std::make_pair (Load, NewInsts);
151
+ }
152
+
153
+ static void eraseNewInstructions (SmallVector<Instruction *> &NewInsts) {
154
+ // Remove in reverse order (uses before defs)
155
+ for (auto it = NewInsts.rbegin (); it != NewInsts.rend (); ++it) {
156
+ (*it)->eraseFromParent ();
157
+ }
158
+ }
159
+
111
160
Value *RandomIRBuilder::findOrCreateSource (BasicBlock &BB,
112
161
ArrayRef<Instruction *> Insts,
113
162
ArrayRef<Value *> Srcs,
@@ -158,19 +207,20 @@ Value *RandomIRBuilder::findOrCreateSource(BasicBlock &BB,
158
207
Module *M = BB.getParent ()->getParent ();
159
208
auto [GV, DidCreate] = findOrCreateGlobalVariable (M, Srcs, Pred);
160
209
Type *Ty = GV->getValueType ();
161
- LoadInst *LoadGV = nullptr ;
162
- if (BB.getTerminator ()) {
163
- LoadGV = new LoadInst (Ty, GV, " LGV " , BB. getFirstInsertionPt () );
164
- } else {
165
- LoadGV = new LoadInst (Ty, GV, " LGV " , &BB);
166
- }
210
+ InsertPosition IP = BB. getTerminator ()
211
+ ? InsertPosition (BB.getFirstInsertionPt ())
212
+ : InsertPosition (&BB );
213
+ // Build a legal load and track new instructions in case a rollback is
214
+ // needed.
215
+ auto [LoadGV, NewInsts] = buildTargetLegalLoad (Ty, GV, IP, M, " LGV " );
167
216
// Because we might be generating new values, we have to check if it
168
217
// matches again.
169
218
if (DidCreate) {
170
219
if (Pred.matches (Srcs, LoadGV)) {
171
220
return LoadGV;
172
221
}
173
- LoadGV->eraseFromParent ();
222
+ // Remove newly inserted instructions
223
+ eraseNewInstructions (NewInsts);
174
224
// If no one is using this GlobalVariable, delete it too.
175
225
if (GV->use_empty ()) {
176
226
GV->eraseFromParent ();
@@ -208,13 +258,18 @@ Value *RandomIRBuilder::newSource(BasicBlock &BB, ArrayRef<Instruction *> Insts,
208
258
}
209
259
// Pick the type independently.
210
260
Type *AccessTy = RS.getSelection ()->getType ();
211
- auto *NewLoad = new LoadInst (AccessTy, Ptr, " L" , IP);
261
+ // Build a legal load and track new instructions in case a rollback is
262
+ // needed.
263
+ auto [NewLoad, NewInsts] =
264
+ buildTargetLegalLoad (AccessTy, Ptr, IP, BB.getModule (), " L" );
212
265
213
266
// Only sample this load if it really matches the descriptor
214
267
if (Pred.matches (Srcs, NewLoad))
215
268
RS.sample (NewLoad, RS.totalWeight ());
216
- else
217
- NewLoad->eraseFromParent ();
269
+ else {
270
+ // Remove newly inserted instructions
271
+ eraseNewInstructions (NewInsts);
272
+ }
218
273
}
219
274
220
275
Value *newSrc = RS.getSelection ();
@@ -320,8 +375,10 @@ Instruction *RandomIRBuilder::connectToSink(BasicBlock &BB,
320
375
std::shuffle (Dominators.begin (), Dominators.end (), Rand);
321
376
for (BasicBlock *Dom : Dominators) {
322
377
for (Instruction &I : *Dom) {
323
- if (isa<PointerType>(I.getType ()))
324
- return new StoreInst (V, &I, Insts.back ()->getIterator ());
378
+ if (isa<PointerType>(I.getType ())) {
379
+ return buildTargetLegalStore (V, &I, Insts.back ()->getIterator (),
380
+ I.getModule ());
381
+ }
325
382
}
326
383
}
327
384
break ;
@@ -344,10 +401,10 @@ Instruction *RandomIRBuilder::connectToSink(BasicBlock &BB,
344
401
// / TODO: allocate a new stack memory.
345
402
return newSink (BB, Insts, V);
346
403
case SinkToGlobalVariable: {
347
- Module *M = BB.getParent ()-> getParent ();
404
+ Module *M = BB.getModule ();
348
405
auto [GV, DidCreate] =
349
406
findOrCreateGlobalVariable (M, {}, fuzzerop::onlyType (V->getType ()));
350
- return new StoreInst (V, GV, Insts.back ()->getIterator ());
407
+ return buildTargetLegalStore (V, GV, Insts.back ()->getIterator (), M );
351
408
}
352
409
case EndOfValueSink:
353
410
default :
@@ -369,7 +426,8 @@ Instruction *RandomIRBuilder::newSink(BasicBlock &BB,
369
426
}
370
427
}
371
428
372
- return new StoreInst (V, Ptr, Insts.back ()->getIterator ());
429
+ return buildTargetLegalStore (V, Ptr, Insts.back ()->getIterator (),
430
+ BB.getModule ());
373
431
}
374
432
375
433
Value *RandomIRBuilder::findPointer (BasicBlock &BB,
0 commit comments