-
Notifications
You must be signed in to change notification settings - Fork 10.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix for a dangling point bug in DeadStoreElimination pass
The patch makes sure that the LastThrowing pointer does not point to any instruction deleted by call to DeleteDeadInstruction. While iterating through the instructions the pass maintains a pointer to the lastThrowing Instruction. A call to deleteDeadInstruction deletes a dead store and other instructions feeding the original dead instruction which also become dead. The instruction pointed by the lastThrowing pointer could also be deleted by the call to DeleteDeadInstruction and thus it becomes a dangling pointer. Because of this, we see an error in the next iteration. In the patch, we maintain a list of throwing instructions encountered previously and use the last non deleted throwing instruction from the container. Reviewers: fhahn, bcahoon, efriedma Reviewed By: fhahn Differential Revision: https://reviews.llvm.org/D65326
- Loading branch information
Showing
2 changed files
with
80 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
41 changes: 41 additions & 0 deletions
41
llvm/test/Transforms/DeadStoreElimination/DeleteThrowableInst.ll
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py | ||
| ; RUN: opt < %s -basicaa -dse -S | FileCheck %s | ||
|
|
||
| declare i8* @_Znwj(i32) local_unnamed_addr | ||
| declare void @foo() readnone | ||
|
|
||
| define void @test1(i8** %ptr) { | ||
| ; CHECK-LABEL: @test1( | ||
| ; CHECK-NEXT: [[VAL:%.*]] = inttoptr i64 23452 to i8* | ||
| ; CHECK-NEXT: store i8* [[VAL]], i8** [[PTR:%.*]] | ||
| ; CHECK-NEXT: ret void | ||
| ; | ||
| %val = inttoptr i64 23452 to i8* | ||
| store i8* %val, i8** %ptr | ||
| %call = call i8* @_Znwj(i32 1) | ||
| store i8* %call, i8** %ptr | ||
| store i8* %val, i8** %ptr | ||
| ret void | ||
| } | ||
|
|
||
| define void @test2(i8** %ptr, i8* %p1, i8* %p2) { | ||
| ; CHECK-LABEL: @test2( | ||
| ; CHECK-NEXT: [[VAL:%.*]] = inttoptr i64 23452 to i8* | ||
| ; CHECK-NEXT: store i8* [[VAL]], i8** [[PTR:%.*]] | ||
| ; CHECK-NEXT: call void @foo() | ||
| ; CHECK-NEXT: store i8* [[P1:%.*]], i8** [[PTR]] | ||
| ; CHECK-NEXT: call void @foo() | ||
| ; CHECK-NEXT: store i8* [[VAL]], i8** [[PTR]] | ||
| ; CHECK-NEXT: ret void | ||
| ; | ||
| %val = inttoptr i64 23452 to i8* | ||
| store i8* %val, i8** %ptr | ||
| call void @foo() | ||
| store i8* %p1, i8** %ptr | ||
| call void @foo() | ||
| store i8* %p2, i8** %ptr | ||
| %call = call i8* @_Znwj(i32 1) | ||
| store i8* %call, i8** %ptr | ||
| store i8* %val, i8** %ptr | ||
| ret void | ||
| } |