File tree 3 files changed +12
-4
lines changed
3 files changed +12
-4
lines changed Original file line number Diff line number Diff line change @@ -477,8 +477,12 @@ impl<'ctx> BasicBlock<'ctx> {
477
477
pub fn replace_all_uses_with ( & self , other : & BasicBlock < ' ctx > ) {
478
478
let value = unsafe { LLVMBasicBlockAsValue ( self . basic_block ) } ;
479
479
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
+ }
482
486
}
483
487
}
484
488
}
Original file line number Diff line number Diff line change @@ -173,8 +173,11 @@ impl<'ctx> Value<'ctx> {
173
173
// REVIEW: I think this is memory safe, though it may result in an IR error
174
174
// if used incorrectly, which is OK.
175
175
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
+ }
178
181
}
179
182
}
180
183
Original file line number Diff line number Diff line change @@ -178,6 +178,7 @@ fn test_rauw() {
178
178
builder. position_at_end ( entry) ;
179
179
let branch_inst = builder. build_unconditional_branch ( bb1) ;
180
180
181
+ bb1. replace_all_uses_with ( & bb1) ; // no-op
181
182
bb1. replace_all_uses_with ( & bb2) ;
182
183
183
184
assert_eq ! ( branch_inst. get_operand( 0 ) . unwrap( ) . right( ) . unwrap( ) , bb2) ;
You can’t perform that action at this time.
0 commit comments