Skip to content

Commit 7eec832

Browse files
FabianWolfffhahn
authored andcommitted
[DSE] Improve handling of strncpy in Dead Store Elimination
Fixes PR#52062 and one of the remaining cases of PR#47644. Reviewed By: fhahn Differential Revision: https://reviews.llvm.org/D114035
1 parent d5de568 commit 7eec832

File tree

2 files changed

+10
-6
lines changed

2 files changed

+10
-6
lines changed

llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1059,8 +1059,13 @@ struct DSEState {
10591059
LibFunc LF;
10601060
if (TLI.getLibFunc(*CB, LF) && TLI.has(LF)) {
10611061
switch (LF) {
1062-
case LibFunc_strcpy:
10631062
case LibFunc_strncpy:
1063+
if (const auto *Len = dyn_cast<ConstantInt>(CB->getArgOperand(2)))
1064+
return MemoryLocation(CB->getArgOperand(0),
1065+
LocationSize::precise(Len->getZExtValue()),
1066+
CB->getAAMetadata());
1067+
LLVM_FALLTHROUGH;
1068+
case LibFunc_strcpy:
10641069
case LibFunc_strcat:
10651070
case LibFunc_strncat:
10661071
return {MemoryLocation::getAfter(CB->getArgOperand(0))};

llvm/test/Transforms/DeadStoreElimination/libcalls.ll

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -435,8 +435,7 @@ declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i1) nounwind
435435
; strncpy -> memset, full overwrite
436436
define void @dse_strncpy_test1(i8* noalias %out, i8* noalias %in) {
437437
; CHECK-LABEL: @dse_strncpy_test1(
438-
; CHECK-NEXT: [[CALL:%.*]] = tail call i8* @strncpy(i8* [[OUT:%.*]], i8* [[IN:%.*]], i64 100)
439-
; CHECK-NEXT: tail call void @llvm.memset.p0i8.i64(i8* [[OUT]], i8 42, i64 100, i1 false)
438+
; CHECK-NEXT: tail call void @llvm.memset.p0i8.i64(i8* [[OUT:%.*]], i8 42, i64 100, i1 false)
440439
; CHECK-NEXT: ret void
441440
;
442441
%call = tail call i8* @strncpy(i8* %out, i8* %in, i64 100)
@@ -472,8 +471,7 @@ define void @dse_strncpy_test3(i8* noalias %out1, i8* noalias %out2, i8* noalias
472471
; memset -> strncpy, full overwrite
473472
define void @dse_strncpy_test4(i8* noalias %out, i8* noalias %in) {
474473
; CHECK-LABEL: @dse_strncpy_test4(
475-
; CHECK-NEXT: tail call void @llvm.memset.p0i8.i64(i8* [[OUT:%.*]], i8 42, i64 100, i1 false)
476-
; CHECK-NEXT: [[CALL:%.*]] = tail call i8* @strncpy(i8* [[OUT]], i8* [[IN:%.*]], i64 100)
474+
; CHECK-NEXT: [[CALL:%.*]] = tail call i8* @strncpy(i8* [[OUT:%.*]], i8* [[IN:%.*]], i64 100)
477475
; CHECK-NEXT: ret void
478476
;
479477
tail call void @llvm.memset.p0i8.i64(i8* %out, i8 42, i64 100, i1 false)
@@ -484,7 +482,8 @@ define void @dse_strncpy_test4(i8* noalias %out, i8* noalias %in) {
484482
; memset -> strncpy, partial overwrite
485483
define void @dse_strncpy_test5(i8* noalias %out, i8* noalias %in) {
486484
; CHECK-LABEL: @dse_strncpy_test5(
487-
; CHECK-NEXT: tail call void @llvm.memset.p0i8.i64(i8* [[OUT:%.*]], i8 42, i64 100, i1 false)
485+
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, i8* [[OUT:%.*]], i64 99
486+
; CHECK-NEXT: tail call void @llvm.memset.p0i8.i64(i8* align 1 [[TMP1]], i8 42, i64 1, i1 false)
488487
; CHECK-NEXT: [[CALL:%.*]] = tail call i8* @strncpy(i8* [[OUT]], i8* [[IN:%.*]], i64 99)
489488
; CHECK-NEXT: ret void
490489
;

0 commit comments

Comments
 (0)