@@ -122,6 +122,9 @@ define i32 @foo(i32 %v0, i32 %v1) {
122
122
BasicBlock *LLVMBB = &*LLVMF.begin ();
123
123
auto LLVMBBIt = LLVMBB->begin ();
124
124
Instruction *LLVMI0 = &*LLVMBBIt++;
125
+ Instruction *LLVMRet = &*LLVMBBIt++;
126
+ Argument *LLVMArg0 = LLVMF.getArg (0 );
127
+ Argument *LLVMArg1 = LLVMF.getArg (1 );
125
128
126
129
auto &F = *Ctx.createFunction (&LLVMF);
127
130
auto &BB = *F.begin ();
@@ -203,6 +206,126 @@ OperandNo: 0
203
206
EXPECT_FALSE (I0->hasNUses (0u ));
204
207
EXPECT_TRUE (I0->hasNUses (1u ));
205
208
EXPECT_FALSE (I0->hasNUses (2u ));
209
+
210
+ // Check User.setOperand().
211
+ Ret->setOperand (0 , Arg0);
212
+ EXPECT_EQ (Ret->getOperand (0 ), Arg0);
213
+ EXPECT_EQ (Ret->getOperandUse (0 ).get (), Arg0);
214
+ EXPECT_EQ (LLVMRet->getOperand (0 ), LLVMArg0);
215
+
216
+ Ret->setOperand (0 , Arg1);
217
+ EXPECT_EQ (Ret->getOperand (0 ), Arg1);
218
+ EXPECT_EQ (Ret->getOperandUse (0 ).get (), Arg1);
219
+ EXPECT_EQ (LLVMRet->getOperand (0 ), LLVMArg1);
220
+ }
221
+
222
+ TEST_F (SandboxIRTest, RUOW) {
223
+ parseIR (C, R"IR(
224
+ declare void @bar0()
225
+ declare void @bar1()
226
+
227
+ @glob0 = global ptr @bar0
228
+ @glob1 = global ptr @bar1
229
+
230
+ define i32 @foo(i32 %arg0, i32 %arg1) {
231
+ %add0 = add i32 %arg0, %arg1
232
+ %gep1 = getelementptr i8, ptr @glob0, i32 1
233
+ %gep2 = getelementptr i8, ptr @glob1, i32 1
234
+ ret i32 %add0
235
+ }
236
+ )IR" );
237
+ llvm::Function &LLVMF = *M->getFunction (" foo" );
238
+ sandboxir::Context Ctx (C);
239
+
240
+ auto &F = *Ctx.createFunction (&LLVMF);
241
+ auto &BB = *F.begin ();
242
+ auto *Arg0 = F.getArg (0 );
243
+ auto *Arg1 = F.getArg (1 );
244
+ auto It = BB.begin ();
245
+ auto *I0 = &*It++;
246
+ auto *I1 = &*It++;
247
+ auto *I2 = &*It++;
248
+ auto *Ret = &*It++;
249
+
250
+ bool Replaced;
251
+ // Try to replace an operand that doesn't match.
252
+ Replaced = I0->replaceUsesOfWith (Ret, Arg1);
253
+ EXPECT_FALSE (Replaced);
254
+ EXPECT_EQ (I0->getOperand (0 ), Arg0);
255
+ EXPECT_EQ (I0->getOperand (1 ), Arg1);
256
+
257
+ // Replace I0 operands when operands differ.
258
+ Replaced = I0->replaceUsesOfWith (Arg0, Arg1);
259
+ EXPECT_TRUE (Replaced);
260
+ EXPECT_EQ (I0->getOperand (0 ), Arg1);
261
+ EXPECT_EQ (I0->getOperand (1 ), Arg1);
262
+
263
+ // Replace I0 operands when operands are the same.
264
+ Replaced = I0->replaceUsesOfWith (Arg1, Arg0);
265
+ EXPECT_TRUE (Replaced);
266
+ EXPECT_EQ (I0->getOperand (0 ), Arg0);
267
+ EXPECT_EQ (I0->getOperand (1 ), Arg0);
268
+
269
+ // Replace Ret operand.
270
+ Replaced = Ret->replaceUsesOfWith (I0, Arg0);
271
+ EXPECT_TRUE (Replaced);
272
+ EXPECT_EQ (Ret->getOperand (0 ), Arg0);
273
+
274
+ // Check RAUW on constant.
275
+ auto *Glob0 = cast<sandboxir::Constant>(I1->getOperand (0 ));
276
+ auto *Glob1 = cast<sandboxir::Constant>(I2->getOperand (0 ));
277
+ auto *Glob0Op = Glob0->getOperand (0 );
278
+ Glob0->replaceUsesOfWith (Glob0Op, Glob1);
279
+ EXPECT_EQ (Glob0->getOperand (0 ), Glob1);
280
+ }
281
+
282
+ TEST_F (SandboxIRTest, RAUW_RUWIf) {
283
+ parseIR (C, R"IR(
284
+ define void @foo(ptr %ptr) {
285
+ %ld0 = load float, ptr %ptr
286
+ %ld1 = load float, ptr %ptr
287
+ store float %ld0, ptr %ptr
288
+ store float %ld0, ptr %ptr
289
+ ret void
290
+ }
291
+ )IR" );
292
+ llvm::Function &LLVMF = *M->getFunction (" foo" );
293
+ sandboxir::Context Ctx (C);
294
+ llvm::BasicBlock *LLVMBB = &*LLVMF.begin ();
295
+
296
+ Ctx.createFunction (&LLVMF);
297
+ auto *BB = cast<sandboxir::BasicBlock>(Ctx.getValue (LLVMBB));
298
+ auto It = BB->begin ();
299
+ sandboxir::Instruction *Ld0 = &*It++;
300
+ sandboxir::Instruction *Ld1 = &*It++;
301
+ sandboxir::Instruction *St0 = &*It++;
302
+ sandboxir::Instruction *St1 = &*It++;
303
+ // Check RUWIf when the lambda returns false.
304
+ Ld0->replaceUsesWithIf (Ld1, [](const sandboxir::Use &Use) { return false ; });
305
+ EXPECT_EQ (St0->getOperand (0 ), Ld0);
306
+ EXPECT_EQ (St1->getOperand (0 ), Ld0);
307
+ // Check RUWIf when the lambda returns true.
308
+ Ld0->replaceUsesWithIf (Ld1, [](const sandboxir::Use &Use) { return true ; });
309
+ EXPECT_EQ (St0->getOperand (0 ), Ld1);
310
+ EXPECT_EQ (St1->getOperand (0 ), Ld1);
311
+ St0->setOperand (0 , Ld0);
312
+ St1->setOperand (0 , Ld0);
313
+ // Check RUWIf user == St0.
314
+ Ld0->replaceUsesWithIf (
315
+ Ld1, [St0](const sandboxir::Use &Use) { return Use.getUser () == St0; });
316
+ EXPECT_EQ (St0->getOperand (0 ), Ld1);
317
+ EXPECT_EQ (St1->getOperand (0 ), Ld0);
318
+ St0->setOperand (0 , Ld0);
319
+ // Check RUWIf user == St1.
320
+ Ld0->replaceUsesWithIf (
321
+ Ld1, [St1](const sandboxir::Use &Use) { return Use.getUser () == St1; });
322
+ EXPECT_EQ (St0->getOperand (0 ), Ld0);
323
+ EXPECT_EQ (St1->getOperand (0 ), Ld1);
324
+ St1->setOperand (0 , Ld0);
325
+ // Check RAUW.
326
+ Ld1->replaceAllUsesWith (Ld0);
327
+ EXPECT_EQ (St0->getOperand (0 ), Ld0);
328
+ EXPECT_EQ (St1->getOperand (0 ), Ld0);
206
329
}
207
330
208
331
// Check that the operands/users are counted correctly.
0 commit comments