[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