Skip to content

Commit c2e2808

Browse files
authored
Merge pull request rust-lang#164 from wasmerio/feature/dont-rauw-yourself
Check for RAUW'ing a value with itself. That's just a no-op.
2 parents b76f8ee + 15396fa commit c2e2808

File tree

3 files changed

+12
-4
lines changed

3 files changed

+12
-4
lines changed

src/basic_block.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -477,8 +477,12 @@ impl<'ctx> BasicBlock<'ctx> {
477477
pub fn replace_all_uses_with(&self, other: &BasicBlock<'ctx>) {
478478
let value = unsafe { LLVMBasicBlockAsValue(self.basic_block) };
479479
let other = unsafe { LLVMBasicBlockAsValue(other.basic_block) };
480-
unsafe {
481-
LLVMReplaceAllUsesWith(value, other);
480+
481+
// LLVM may infinite-loop when they aren't distinct, which is UB in C++.
482+
if value != other {
483+
unsafe {
484+
LLVMReplaceAllUsesWith(value, other);
485+
}
482486
}
483487
}
484488
}

src/values/mod.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -173,8 +173,11 @@ impl<'ctx> Value<'ctx> {
173173
// REVIEW: I think this is memory safe, though it may result in an IR error
174174
// if used incorrectly, which is OK.
175175
fn replace_all_uses_with(&self, other: LLVMValueRef) {
176-
unsafe {
177-
LLVMReplaceAllUsesWith(self.value, other)
176+
// LLVM may infinite-loop when they aren't distinct, which is UB in C++.
177+
if self.value != other {
178+
unsafe {
179+
LLVMReplaceAllUsesWith(self.value, other)
180+
}
178181
}
179182
}
180183

tests/all/test_basic_block.rs

+1
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ fn test_rauw() {
178178
builder.position_at_end(entry);
179179
let branch_inst = builder.build_unconditional_branch(bb1);
180180

181+
bb1.replace_all_uses_with(&bb1); // no-op
181182
bb1.replace_all_uses_with(&bb2);
182183

183184
assert_eq!(branch_inst.get_operand(0).unwrap().right().unwrap(), bb2);

0 commit comments

Comments
 (0)