[llvm] 2807c42 - [InstCombine] add a strnlen handler stub.
Martin Sebor via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 26 13:03:21 PDT 2022
Author: Martin Sebor
Date: 2022-04-26T14:02:49-06:00
New Revision: 2807c420cd23dac7f7624c8f9038c2ec251831d9
URL: https://github.com/llvm/llvm-project/commit/2807c420cd23dac7f7624c8f9038c2ec251831d9
DIFF: https://github.com/llvm/llvm-project/commit/2807c420cd23dac7f7624c8f9038c2ec251831d9.diff
LOG: [InstCombine] add a strnlen handler stub.
Reviewed By: nikic
Differential Revision: https://reviews.llvm.org/D123815
Added:
Modified:
llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h
llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
llvm/test/Transforms/InstCombine/strnlen-1.ll
llvm/test/Transforms/InstCombine/strnlen-2.ll
llvm/test/Transforms/InstCombine/strnlen-3.ll
llvm/test/Transforms/InstCombine/strnlen-5.ll
llvm/test/Transforms/InstCombine/strnlen-6.ll
Removed:
################################################################################
diff --git a/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h b/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h
index 9a3af3d66a72a..7eca16275cbbb 100644
--- a/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h
+++ b/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h
@@ -163,6 +163,7 @@ class LibCallSimplifier {
Value *optimizeStpCpy(CallInst *CI, IRBuilderBase &B);
Value *optimizeStrNCpy(CallInst *CI, IRBuilderBase &B);
Value *optimizeStrLen(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeStrNLen(CallInst *CI, IRBuilderBase &B);
Value *optimizeStrPBrk(CallInst *CI, IRBuilderBase &B);
Value *optimizeStrTo(CallInst *CI, IRBuilderBase &B);
Value *optimizeStrSpn(CallInst *CI, IRBuilderBase &B);
diff --git a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
index e130ffbaf41fa..455632730570d 100644
--- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
@@ -717,6 +717,13 @@ Value *LibCallSimplifier::optimizeStrLen(CallInst *CI, IRBuilderBase &B) {
return nullptr;
}
+Value *LibCallSimplifier::optimizeStrNLen(CallInst *CI, IRBuilderBase &B) {
+ Value *Bound = CI->getArgOperand(1);
+ if (isKnownNonZero(Bound, DL))
+ annotateNonNullNoUndefBasedOnAccess(CI, 0);
+ return nullptr;
+}
+
Value *LibCallSimplifier::optimizeWcslen(CallInst *CI, IRBuilderBase &B) {
Module &M = *CI->getModule();
unsigned WCharSize = TLI->getWCharSize(M) * 8;
@@ -2879,6 +2886,8 @@ Value *LibCallSimplifier::optimizeStringMemoryLibCall(CallInst *CI,
return optimizeStrNCpy(CI, Builder);
case LibFunc_strlen:
return optimizeStrLen(CI, Builder);
+ case LibFunc_strnlen:
+ return optimizeStrNLen(CI, Builder);
case LibFunc_strpbrk:
return optimizeStrPBrk(CI, Builder);
case LibFunc_strndup:
diff --git a/llvm/test/Transforms/InstCombine/strnlen-1.ll b/llvm/test/Transforms/InstCombine/strnlen-1.ll
index 0fb94dba6c0ff..f8fabbe8fe615 100644
--- a/llvm/test/Transforms/InstCombine/strnlen-1.ll
+++ b/llvm/test/Transforms/InstCombine/strnlen-1.ll
@@ -10,6 +10,47 @@ declare i64 @strnlen(i8*, i64)
@s5_3 = constant [9 x i8] c"12345\00xyz"
+; Verify that the strnlen pointer argument is not annotated nonnull when
+; nothing is known about the bound.
+
+define i64 @no_access_strnlen_p_n(i8* %ptr, i64 %n) {
+; CHECK-LABEL: @no_access_strnlen_p_n(
+; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* [[PTR:%.*]], i64 [[N:%.*]])
+; CHECK-NEXT: ret i64 [[LEN]]
+;
+ %len = call i64 @strnlen(i8* %ptr, i64 %n)
+ ret i64 %len
+}
+
+
+; Verify that the strnlen pointer argument is annotated dereferenceable(1)
+; (and not more) when the constant bound is greater than 1.
+
+define i64 @access_strnlen_p_2(i8* %ptr) {
+; CHECK-LABEL: @access_strnlen_p_2(
+; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* noundef nonnull dereferenceable(1) [[PTR:%.*]], i64 2)
+; CHECK-NEXT: ret i64 [[LEN]]
+;
+ %len = call i64 @strnlen(i8* noundef nonnull dereferenceable(1) %ptr, i64 2)
+ ret i64 %len
+}
+
+
+; Verify that the strnlen pointer argument is annotated nonnull etc.,
+; when the bound is known to be nonzero.
+
+define i64 @access_strnlen_p_nz(i8* %ptr, i64 %n) {
+; CHECK-LABEL: @access_strnlen_p_nz(
+; CHECK-NEXT: [[NNZ:%.*]] = or i64 [[N:%.*]], 1
+; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* noundef nonnull dereferenceable(1) [[PTR:%.*]], i64 [[NNZ]])
+; CHECK-NEXT: ret i64 [[LEN]]
+;
+ %nnz = or i64 %n, 1
+ %len = call i64 @strnlen(i8* noundef nonnull dereferenceable(1) %ptr, i64 %nnz)
+ ret i64 %len
+}
+
+
; Fold strnlen(s5, 0) to 0.
define i64 @fold_strnlen_s5_0() {
@@ -27,7 +68,7 @@ define i64 @fold_strnlen_s5_0() {
define i64 @fold_strnlen_s5_4() {
; CHECK-LABEL: @fold_strnlen_s5_4(
-; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @s5, i64 0, i64 0), i64 4)
+; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([6 x i8], [6 x i8]* @s5, i64 0, i64 0), i64 4)
; CHECK-NEXT: ret i64 [[LEN]]
;
%ptr = getelementptr [6 x i8], [6 x i8]* @s5, i32 0, i32 0
@@ -40,7 +81,7 @@ define i64 @fold_strnlen_s5_4() {
define i64 @fold_strnlen_s5_5() {
; CHECK-LABEL: @fold_strnlen_s5_5(
-; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @s5, i64 0, i64 0), i64 5)
+; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([6 x i8], [6 x i8]* @s5, i64 0, i64 0), i64 5)
; CHECK-NEXT: ret i64 [[LEN]]
;
%ptr = getelementptr [6 x i8], [6 x i8]* @s5, i32 0, i32 0
@@ -53,7 +94,7 @@ define i64 @fold_strnlen_s5_5() {
define i64 @fold_strnlen_s5_m1() {
; CHECK-LABEL: @fold_strnlen_s5_m1(
-; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @s5, i64 0, i64 0), i64 -1)
+; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([6 x i8], [6 x i8]* @s5, i64 0, i64 0), i64 -1)
; CHECK-NEXT: ret i64 [[LEN]]
;
%ptr = getelementptr [6 x i8], [6 x i8]* @s5, i32 0, i32 0
@@ -66,7 +107,7 @@ define i64 @fold_strnlen_s5_m1() {
define i64 @fold_strnlen_s5_3_p4_5() {
; CHECK-LABEL: @fold_strnlen_s5_3_p4_5(
-; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* getelementptr inbounds ([9 x i8], [9 x i8]* @s5_3, i64 0, i64 4), i64 5)
+; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([9 x i8], [9 x i8]* @s5_3, i64 0, i64 4), i64 5)
; CHECK-NEXT: ret i64 [[LEN]]
;
%ptr = getelementptr [9 x i8], [9 x i8]* @s5_3, i32 0, i32 4
@@ -79,7 +120,7 @@ define i64 @fold_strnlen_s5_3_p4_5() {
define i64 @fold_strnlen_s5_3_p5_5() {
; CHECK-LABEL: @fold_strnlen_s5_3_p5_5(
-; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* getelementptr inbounds ([9 x i8], [9 x i8]* @s5_3, i64 0, i64 5), i64 5)
+; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([9 x i8], [9 x i8]* @s5_3, i64 0, i64 5), i64 5)
; CHECK-NEXT: ret i64 [[LEN]]
;
%ptr = getelementptr [9 x i8], [9 x i8]* @s5_3, i32 0, i32 5
@@ -92,7 +133,7 @@ define i64 @fold_strnlen_s5_3_p5_5() {
define i64 @fold_strnlen_s5_3_p6_5() {
; CHECK-LABEL: @fold_strnlen_s5_3_p6_5(
-; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* getelementptr inbounds ([9 x i8], [9 x i8]* @s5_3, i64 0, i64 6), i64 5)
+; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([9 x i8], [9 x i8]* @s5_3, i64 0, i64 6), i64 5)
; CHECK-NEXT: ret i64 [[LEN]]
;
%ptr = getelementptr [9 x i8], [9 x i8]* @s5_3, i32 0, i32 6
diff --git a/llvm/test/Transforms/InstCombine/strnlen-2.ll b/llvm/test/Transforms/InstCombine/strnlen-2.ll
index f46886598e318..a58ea6b296369 100644
--- a/llvm/test/Transforms/InstCombine/strnlen-2.ll
+++ b/llvm/test/Transforms/InstCombine/strnlen-2.ll
@@ -33,7 +33,7 @@ define i64 @fold_strnlen_s3_s5_0(i1 %C) {
define i64 @fold_strnlen_s3_s5_1(i1 %C) {
; CHECK-LABEL: @fold_strnlen_s3_s5_1(
; CHECK-NEXT: [[PTR:%.*]] = select i1 [[C:%.*]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @s3, i64 0, i64 0), i8* getelementptr inbounds ([7 x i8], [7 x i8]* @s6, i64 0, i64 0)
-; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* [[PTR]], i64 1)
+; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* noundef nonnull dereferenceable(1) [[PTR]], i64 1)
; CHECK-NEXT: ret i64 [[LEN]]
;
%ptr = select i1 %C, i8* getelementptr ([4 x i8], [4 x i8]* @s3, i64 0, i64 0), i8* getelementptr ([7 x i8], [7 x i8]* @s6, i64 0, i64 0)
@@ -48,7 +48,7 @@ define i64 @fold_strnlen_s3_s5_1(i1 %C) {
define i64 @fold_strnlen_s3_s5_3(i1 %C) {
; CHECK-LABEL: @fold_strnlen_s3_s5_3(
; CHECK-NEXT: [[PTR:%.*]] = select i1 [[C:%.*]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @s3, i64 0, i64 0), i8* getelementptr inbounds ([7 x i8], [7 x i8]* @s6, i64 0, i64 0)
-; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* [[PTR]], i64 3)
+; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* noundef nonnull dereferenceable(1) [[PTR]], i64 3)
; CHECK-NEXT: ret i64 [[LEN]]
;
%ptr = select i1 %C, i8* getelementptr ([4 x i8], [4 x i8]* @s3, i64 0, i64 0), i8* getelementptr ([7 x i8], [7 x i8]* @s6, i64 0, i64 0)
@@ -63,7 +63,7 @@ define i64 @fold_strnlen_s3_s5_3(i1 %C) {
define i64 @fold_strnlen_s3_s5_4(i1 %C) {
; CHECK-LABEL: @fold_strnlen_s3_s5_4(
; CHECK-NEXT: [[PTR:%.*]] = select i1 [[C:%.*]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @s3, i64 0, i64 0), i8* getelementptr inbounds ([7 x i8], [7 x i8]* @s6, i64 0, i64 0)
-; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* [[PTR]], i64 4)
+; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* noundef nonnull dereferenceable(1) [[PTR]], i64 4)
; CHECK-NEXT: ret i64 [[LEN]]
;
%ptr = select i1 %C, i8* getelementptr ([4 x i8], [4 x i8]* @s3, i64 0, i64 0), i8* getelementptr ([7 x i8], [7 x i8]* @s6, i64 0, i64 0)
@@ -78,7 +78,7 @@ define i64 @fold_strnlen_s3_s5_4(i1 %C) {
define i64 @fold_strnlen_s3_s5_5(i1 %C) {
; CHECK-LABEL: @fold_strnlen_s3_s5_5(
; CHECK-NEXT: [[PTR:%.*]] = select i1 [[C:%.*]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @s3, i64 0, i64 0), i8* getelementptr inbounds ([7 x i8], [7 x i8]* @s6, i64 0, i64 0)
-; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* [[PTR]], i64 5)
+; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* noundef nonnull dereferenceable(1) [[PTR]], i64 5)
; CHECK-NEXT: ret i64 [[LEN]]
;
%ptr = select i1 %C, i8* getelementptr ([4 x i8], [4 x i8]* @s3, i64 0, i64 0), i8* getelementptr ([7 x i8], [7 x i8]* @s6, i64 0, i64 0)
@@ -93,7 +93,7 @@ define i64 @fold_strnlen_s3_s5_5(i1 %C) {
define i64 @fold_strnlen_s5_6(i1 %C) {
; CHECK-LABEL: @fold_strnlen_s5_6(
; CHECK-NEXT: [[PTR:%.*]] = select i1 [[C:%.*]], i8* getelementptr inbounds ([6 x i8], [6 x i8]* @s5, i64 0, i64 0), i8* getelementptr inbounds ([7 x i8], [7 x i8]* @s6, i64 0, i64 0)
-; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* [[PTR]], i64 6)
+; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* noundef nonnull dereferenceable(1) [[PTR]], i64 6)
; CHECK-NEXT: ret i64 [[LEN]]
;
@@ -113,7 +113,7 @@ define i64 @fold_strnlen_s3_s5_s7_4(i32 %X) {
; CHECK-NEXT: [[X_EQ_5:%.*]] = icmp eq i32 [[X]], 5
; CHECK-NEXT: [[SEL_X_EQ_5:%.*]] = select i1 [[X_EQ_5]], i8* getelementptr inbounds ([6 x i8], [6 x i8]* @s5, i64 0, i64 0), i8* getelementptr inbounds ([8 x i8], [8 x i8]* @s7, i64 0, i64 0)
; CHECK-NEXT: [[SEL_X_EQ_3:%.*]] = select i1 [[X_EQ_3]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @s3, i64 0, i64 0), i8* [[SEL_X_EQ_5]]
-; CHECK-NEXT: [[LEN:%.*]] = tail call i64 @strnlen(i8* [[SEL_X_EQ_3]], i64 4)
+; CHECK-NEXT: [[LEN:%.*]] = tail call i64 @strnlen(i8* noundef nonnull dereferenceable(1) [[SEL_X_EQ_3]], i64 4)
; CHECK-NEXT: ret i64 [[LEN]]
;
@@ -136,7 +136,7 @@ define i64 @fold_strnlen_s3_s5_s7_6(i32 %X) {
; CHECK-NEXT: [[X_EQ_5:%.*]] = icmp eq i32 [[X]], 5
; CHECK-NEXT: [[SEL_X_EQ_5:%.*]] = select i1 [[X_EQ_5]], i8* getelementptr inbounds ([6 x i8], [6 x i8]* @s5, i64 0, i64 0), i8* getelementptr inbounds ([8 x i8], [8 x i8]* @s7, i64 0, i64 0)
; CHECK-NEXT: [[SEL_X_EQ_3:%.*]] = select i1 [[X_EQ_3]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @s3, i64 0, i64 0), i8* [[SEL_X_EQ_5]]
-; CHECK-NEXT: [[LEN:%.*]] = tail call i64 @strnlen(i8* [[SEL_X_EQ_3]], i64 6)
+; CHECK-NEXT: [[LEN:%.*]] = tail call i64 @strnlen(i8* noundef nonnull dereferenceable(1) [[SEL_X_EQ_3]], i64 6)
; CHECK-NEXT: ret i64 [[LEN]]
;
@@ -159,7 +159,7 @@ define i64 @fold_strnlen_s3_s5_s7_8(i32 %X) {
; CHECK-NEXT: [[X_EQ_5:%.*]] = icmp eq i32 [[X]], 5
; CHECK-NEXT: [[SEL_X_EQ_5:%.*]] = select i1 [[X_EQ_5]], i8* getelementptr inbounds ([6 x i8], [6 x i8]* @s5, i64 0, i64 0), i8* getelementptr inbounds ([8 x i8], [8 x i8]* @s7, i64 0, i64 0)
; CHECK-NEXT: [[SEL_X_EQ_3:%.*]] = select i1 [[X_EQ_3]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @s3, i64 0, i64 0), i8* [[SEL_X_EQ_5]]
-; CHECK-NEXT: [[LEN:%.*]] = tail call i64 @strnlen(i8* [[SEL_X_EQ_3]], i64 8)
+; CHECK-NEXT: [[LEN:%.*]] = tail call i64 @strnlen(i8* noundef nonnull dereferenceable(1) [[SEL_X_EQ_3]], i64 8)
; CHECK-NEXT: ret i64 [[LEN]]
;
diff --git a/llvm/test/Transforms/InstCombine/strnlen-3.ll b/llvm/test/Transforms/InstCombine/strnlen-3.ll
index 9128d49b0cece..9d1004a1b0800 100644
--- a/llvm/test/Transforms/InstCombine/strnlen-3.ll
+++ b/llvm/test/Transforms/InstCombine/strnlen-3.ll
@@ -49,7 +49,7 @@ define i64 @call_strnlen_sx_pi_n(i64 %i, i64 %n) {
define i64 @call_strnlen_a3_pi_2(i64 %i) {
; CHECK-LABEL: @call_strnlen_a3_pi_2(
; CHECK-NEXT: [[PTR:%.*]] = getelementptr inbounds [3 x i8], [3 x i8]* @a3, i64 0, i64 [[I:%.*]]
-; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* nonnull [[PTR]], i64 2)
+; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* noundef nonnull [[PTR]], i64 2)
; CHECK-NEXT: ret i64 [[LEN]]
;
@@ -64,7 +64,7 @@ define i64 @call_strnlen_a3_pi_2(i64 %i) {
define i64 @call_strnlen_a3_pi_3(i64 %i) {
; CHECK-LABEL: @call_strnlen_a3_pi_3(
; CHECK-NEXT: [[PTR:%.*]] = getelementptr inbounds [3 x i8], [3 x i8]* @a3, i64 0, i64 [[I:%.*]]
-; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* nonnull [[PTR]], i64 3)
+; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* noundef nonnull [[PTR]], i64 3)
; CHECK-NEXT: ret i64 [[LEN]]
;
@@ -162,7 +162,7 @@ define i64 @fold_strnlen_s3_n(i64 %n) {
define i64 @fold_strnlen_a3_pi_2(i64 %i) {
; CHECK-LABEL: @fold_strnlen_a3_pi_2(
; CHECK-NEXT: [[PTR:%.*]] = getelementptr inbounds [3 x i8], [3 x i8]* @a3, i64 0, i64 [[I:%.*]]
-; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* nonnull [[PTR]], i64 2)
+; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* noundef nonnull [[PTR]], i64 2)
; CHECK-NEXT: ret i64 [[LEN]]
;
@@ -177,7 +177,7 @@ define i64 @fold_strnlen_a3_pi_2(i64 %i) {
define i64 @fold_strnlen_s3_pi_2(i64 %i) {
; CHECK-LABEL: @fold_strnlen_s3_pi_2(
; CHECK-NEXT: [[PTR:%.*]] = getelementptr inbounds [4 x i8], [4 x i8]* @s3, i64 0, i64 [[I:%.*]]
-; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* nonnull [[PTR]], i64 2)
+; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* noundef nonnull [[PTR]], i64 2)
; CHECK-NEXT: ret i64 [[LEN]]
;
@@ -192,7 +192,7 @@ define i64 @fold_strnlen_s3_pi_2(i64 %i) {
define i64 @fold_strnlen_s3_pi_3(i64 %i) {
; CHECK-LABEL: @fold_strnlen_s3_pi_3(
; CHECK-NEXT: [[PTR:%.*]] = getelementptr inbounds [4 x i8], [4 x i8]* @s3, i64 0, i64 [[I:%.*]]
-; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* nonnull [[PTR]], i64 3)
+; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* noundef nonnull [[PTR]], i64 3)
; CHECK-NEXT: ret i64 [[LEN]]
;
@@ -223,7 +223,7 @@ define i64 @fold_strnlen_s3_pi_n(i64 %i, i64 %n) {
define i64 @call_strnlen_s5_3_pi_2(i64 %i) {
; CHECK-LABEL: @call_strnlen_s5_3_pi_2(
; CHECK-NEXT: [[PTR:%.*]] = getelementptr inbounds [10 x i8], [10 x i8]* @s5_3, i64 0, i64 [[I:%.*]]
-; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* nonnull [[PTR]], i64 2)
+; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* noundef nonnull [[PTR]], i64 2)
; CHECK-NEXT: ret i64 [[LEN]]
;
diff --git a/llvm/test/Transforms/InstCombine/strnlen-5.ll b/llvm/test/Transforms/InstCombine/strnlen-5.ll
index 46f9e8a7223e3..125ffda245892 100644
--- a/llvm/test/Transforms/InstCombine/strnlen-5.ll
+++ b/llvm/test/Transforms/InstCombine/strnlen-5.ll
@@ -47,7 +47,7 @@ define i1 @fold_strnlen_ax_0_gtz() {
define i1 @fold_strnlen_ax_1_eqz() {
; CHECK-LABEL: @fold_strnlen_ax_1_eqz(
-; CHECK-NEXT: [[LEN:%.*]] = tail call i64 @strnlen(i8* getelementptr inbounds ([0 x i8], [0 x i8]* @ax, i64 0, i64 0), i64 1)
+; CHECK-NEXT: [[LEN:%.*]] = tail call i64 @strnlen(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([0 x i8], [0 x i8]* @ax, i64 0, i64 0), i64 1)
; CHECK-NEXT: [[EQZ:%.*]] = icmp eq i64 [[LEN]], 0
; CHECK-NEXT: ret i1 [[EQZ]]
;
@@ -63,7 +63,7 @@ define i1 @fold_strnlen_ax_1_eqz() {
define i1 @fold_strnlen_ax_1_neqz() {
; CHECK-LABEL: @fold_strnlen_ax_1_neqz(
-; CHECK-NEXT: [[LEN:%.*]] = tail call i64 @strnlen(i8* getelementptr inbounds ([0 x i8], [0 x i8]* @ax, i64 0, i64 0), i64 1)
+; CHECK-NEXT: [[LEN:%.*]] = tail call i64 @strnlen(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([0 x i8], [0 x i8]* @ax, i64 0, i64 0), i64 1)
; CHECK-NEXT: [[NEZ:%.*]] = icmp ne i64 [[LEN]], 0
; CHECK-NEXT: ret i1 [[NEZ]]
;
@@ -79,7 +79,7 @@ define i1 @fold_strnlen_ax_1_neqz() {
define i1 @fold_strnlen_ax_9_eqz() {
; CHECK-LABEL: @fold_strnlen_ax_9_eqz(
-; CHECK-NEXT: [[LEN:%.*]] = tail call i64 @strnlen(i8* getelementptr inbounds ([0 x i8], [0 x i8]* @ax, i64 0, i64 0), i64 9)
+; CHECK-NEXT: [[LEN:%.*]] = tail call i64 @strnlen(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([0 x i8], [0 x i8]* @ax, i64 0, i64 0), i64 9)
; CHECK-NEXT: [[EQZ:%.*]] = icmp eq i64 [[LEN]], 0
; CHECK-NEXT: ret i1 [[EQZ]]
;
@@ -112,7 +112,7 @@ define i1 @call_strnlen_ax_n_eqz(i64 %n) {
define i1 @fold_strnlen_ax_nz_eqz(i64 %n) {
; CHECK-LABEL: @fold_strnlen_ax_nz_eqz(
; CHECK-NEXT: [[MAX:%.*]] = or i64 [[N:%.*]], 1
-; CHECK-NEXT: [[LEN:%.*]] = tail call i64 @strnlen(i8* getelementptr inbounds ([0 x i8], [0 x i8]* @ax, i64 0, i64 0), i64 [[MAX]])
+; CHECK-NEXT: [[LEN:%.*]] = tail call i64 @strnlen(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([0 x i8], [0 x i8]* @ax, i64 0, i64 0), i64 [[MAX]])
; CHECK-NEXT: [[EQZ:%.*]] = icmp eq i64 [[LEN]], 0
; CHECK-NEXT: ret i1 [[EQZ]]
;
@@ -130,7 +130,7 @@ define i1 @fold_strnlen_ax_nz_eqz(i64 %n) {
define i1 @fold_strnlen_ax_nz_gtz(i64 %n) {
; CHECK-LABEL: @fold_strnlen_ax_nz_gtz(
; CHECK-NEXT: [[MAX:%.*]] = or i64 [[N:%.*]], 1
-; CHECK-NEXT: [[LEN:%.*]] = tail call i64 @strnlen(i8* getelementptr inbounds ([0 x i8], [0 x i8]* @ax, i64 0, i64 0), i64 [[MAX]])
+; CHECK-NEXT: [[LEN:%.*]] = tail call i64 @strnlen(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([0 x i8], [0 x i8]* @ax, i64 0, i64 0), i64 [[MAX]])
; CHECK-NEXT: [[GTZ:%.*]] = icmp ne i64 [[LEN]], 0
; CHECK-NEXT: ret i1 [[GTZ]]
;
@@ -150,7 +150,7 @@ define i1 @fold_strnlen_a5_pi_nz_eqz(i64 %i, i64 %n) {
; CHECK-LABEL: @fold_strnlen_a5_pi_nz_eqz(
; CHECK-NEXT: [[NZ:%.*]] = or i64 [[N:%.*]], 1
; CHECK-NEXT: [[PTR:%.*]] = getelementptr inbounds [5 x i8], [5 x i8]* @a5, i64 0, i64 [[I:%.*]]
-; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* nonnull [[PTR]], i64 [[NZ]])
+; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* noundef nonnull [[PTR]], i64 [[NZ]])
; CHECK-NEXT: [[EQZ:%.*]] = icmp eq i64 [[LEN]], 0
; CHECK-NEXT: ret i1 [[EQZ]]
;
@@ -171,7 +171,7 @@ define i1 @fold_strnlen_s5_pi_nz_eqz(i64 %i, i64 %n) {
; CHECK-LABEL: @fold_strnlen_s5_pi_nz_eqz(
; CHECK-NEXT: [[NZ:%.*]] = or i64 [[N:%.*]], 1
; CHECK-NEXT: [[PTR:%.*]] = getelementptr inbounds [6 x i8], [6 x i8]* @s5, i64 0, i64 [[I:%.*]]
-; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* nonnull [[PTR]], i64 [[NZ]])
+; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* noundef nonnull [[PTR]], i64 [[NZ]])
; CHECK-NEXT: [[EQZ:%.*]] = icmp eq i64 [[LEN]], 0
; CHECK-NEXT: ret i1 [[EQZ]]
;
diff --git a/llvm/test/Transforms/InstCombine/strnlen-6.ll b/llvm/test/Transforms/InstCombine/strnlen-6.ll
index 91c85825ba4ca..64d94e401d3e6 100644
--- a/llvm/test/Transforms/InstCombine/strnlen-6.ll
+++ b/llvm/test/Transforms/InstCombine/strnlen-6.ll
@@ -16,7 +16,7 @@ declare i64 @strnlen(i8*, i64)
define i64 @deref_strnlen_ecp_3() {
; CHECK-LABEL: @deref_strnlen_ecp_3(
; CHECK-NEXT: [[PTR:%.*]] = load i8*, i8** @ecp, align 8
-; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* [[PTR]], i64 3)
+; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* noundef nonnull dereferenceable(1) [[PTR]], i64 3)
; CHECK-NEXT: ret i64 [[LEN]]
;
%ptr = load i8*, i8** @ecp
@@ -32,7 +32,7 @@ define i64 @deref_strnlen_ecp_nz(i64 %n) {
; CHECK-LABEL: @deref_strnlen_ecp_nz(
; CHECK-NEXT: [[NONZERO:%.*]] = or i64 [[N:%.*]], 1
; CHECK-NEXT: [[PTR:%.*]] = load i8*, i8** @ecp, align 8
-; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* [[PTR]], i64 [[NONZERO]])
+; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* noundef nonnull dereferenceable(1) [[PTR]], i64 [[NONZERO]])
; CHECK-NEXT: ret i64 [[LEN]]
;
%nonzero = or i64 %n, 1
More information about the llvm-commits
mailing list