Skip to content

Commit 0482ca8

Browse files
committed
Merging r369168:
------------------------------------------------------------------------ r369168 | spatel | 2019-08-17 01:10:34 +0200 (Sat, 17 Aug 2019) | 16 lines [CodeGenPrepare] Fix use-after-free If OptimizeExtractBits() encountered a shift instruction with no operands at all, it would erase the instruction, but still return false. This previously didn’t matter because its caller would always return after processing the instruction, but https://reviews.llvm.org/D63233 changed the function’s caller to fall through if it returned false, which would then cause a use-after-free detectable by ASAN. This change makes OptimizeExtractBits return true if it removes a shift instruction with no users, terminating processing of the instruction. Patch by: @brentdax (Brent Royal-Gordon) Differential Revision: https://reviews.llvm.org/D66330 ------------------------------------------------------------------------ llvm-svn: 369355
1 parent 10f293f commit 0482ca8

File tree

2 files changed

+19
-1
lines changed

2 files changed

+19
-1
lines changed

llvm/lib/CodeGen/CodeGenPrepare.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1682,10 +1682,11 @@ static bool OptimizeExtractBits(BinaryOperator *ShiftI, ConstantInt *CI,
16821682
TheUse = InsertedShift;
16831683
}
16841684

1685-
// If we removed all uses, nuke the shift.
1685+
// If we removed all uses, or there are none, nuke the shift.
16861686
if (ShiftI->use_empty()) {
16871687
salvageDebugInfo(*ShiftI);
16881688
ShiftI->eraseFromParent();
1689+
MadeChange = true;
16891690
}
16901691

16911692
return MadeChange;

llvm/test/Transforms/CodeGenPrepare/sink-shift-and-trunc.ll

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,23 @@ return: ; preds = %if.then17, %if.end1
5858
ret i32 %retval.0, !dbg !63
5959
}
6060

61+
; CodeGenPrepare was erasing the unused lshr instruction, but then further
62+
; processing the instruction after it was freed. If this bug is still present,
63+
; this test will always crash in an LLVM built with ASAN enabled, and may
64+
; crash even if ASAN is not enabled.
65+
66+
define i32 @shift_unused(i32 %a) {
67+
; CHECK-LABEL: @shift_unused(
68+
; CHECK-NEXT: BB2:
69+
; CHECK-NEXT: ret i32 [[A:%.*]]
70+
;
71+
%as = lshr i32 %a, 3
72+
br label %BB2
73+
74+
BB2:
75+
ret i32 %a
76+
}
77+
6178
; CHECK: [[shift1_loc]] = !DILocation(line: 1
6279
; CHECK: [[trunc1_loc]] = !DILocation(line: 2
6380
; CHECK: [[shift2_loc]] = !DILocation(line: 3

0 commit comments

Comments
 (0)