1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; Test that the strstr library call simplifier works correctly. 3; 4; RUN: opt < %s -passes=instcombine -S | FileCheck %s 5 6target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" 7 8@.str = private constant [1 x i8] zeroinitializer 9@.str1 = private constant [2 x i8] c"a\00" 10@.str2 = private constant [6 x i8] c"abcde\00" 11@.str3 = private constant [4 x i8] c"bcd\00" 12 13declare ptr @strstr(ptr, ptr) 14 15; Check strstr(str, "") -> str. 16 17define ptr @test_simplify1(ptr %str) { 18; CHECK-LABEL: @test_simplify1( 19; CHECK-NEXT: ret ptr [[STR:%.*]] 20; 21 %ret = call ptr @strstr(ptr %str, ptr @.str) 22 ret ptr %ret 23} 24 25; Check strstr(str, "a") -> strchr(str, 'a'). 26 27define ptr @test_simplify2(ptr %str) { 28; CHECK-LABEL: @test_simplify2( 29; CHECK-NEXT: [[STRCHR:%.*]] = call ptr @strchr(ptr noundef nonnull dereferenceable(1) [[STR:%.*]], i32 97) 30; CHECK-NEXT: ret ptr [[STRCHR]] 31; 32 %ret = call ptr @strstr(ptr %str, ptr @.str1) 33 ret ptr %ret 34} 35 36; Check strstr("abcde", "bcd") -> "abcde" + 1. 37 38define ptr @test_simplify3() { 39; CHECK-LABEL: @test_simplify3( 40; CHECK-NEXT: ret ptr getelementptr inbounds nuw (i8, ptr @.str2, i64 1) 41; 42 %ret = call ptr @strstr(ptr @.str2, ptr @.str3) 43 ret ptr %ret 44} 45 46; Check strstr(str, str) -> str. 47 48define ptr @test_simplify4(ptr %str) { 49; CHECK-LABEL: @test_simplify4( 50; CHECK-NEXT: ret ptr [[STR:%.*]] 51; 52 %ret = call ptr @strstr(ptr %str, ptr %str) 53 ret ptr %ret 54} 55 56; Check strstr(str, pat) == str -> strncmp(str, pat, strlen(str)) == 0. 57 58define i1 @test_simplify5(ptr %str, ptr %pat) { 59; CHECK-LABEL: @test_simplify5( 60; CHECK-NEXT: [[STRLEN:%.*]] = call i64 @strlen(ptr noundef nonnull dereferenceable(1) [[PAT:%.*]]) 61; CHECK-NEXT: [[STRNCMP:%.*]] = call i32 @strncmp(ptr [[STR:%.*]], ptr nonnull [[PAT]], i64 [[STRLEN]]) 62; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[STRNCMP]], 0 63; CHECK-NEXT: ret i1 [[CMP1]] 64; 65 %ret = call ptr @strstr(ptr %str, ptr %pat) 66 %cmp = icmp eq ptr %ret, %str 67 ret i1 %cmp 68} 69 70define ptr @test1(ptr %str1, ptr %str2) { 71; CHECK-LABEL: @test1( 72; CHECK-NEXT: [[RET:%.*]] = call ptr @strstr(ptr noundef nonnull dereferenceable(1) [[STR1:%.*]], ptr noundef nonnull dereferenceable(1) [[STR2:%.*]]) 73; CHECK-NEXT: ret ptr [[RET]] 74; 75 %ret = call ptr @strstr(ptr %str1, ptr %str2) 76 ret ptr %ret 77} 78 79define ptr @test2(ptr %str1, ptr %str2) null_pointer_is_valid { 80; CHECK-LABEL: @test2( 81; CHECK-NEXT: [[RET:%.*]] = call ptr @strstr(ptr noundef [[STR1:%.*]], ptr noundef [[STR2:%.*]]) 82; CHECK-NEXT: ret ptr [[RET]] 83; 84 %ret = call ptr @strstr(ptr %str1, ptr %str2) 85 ret ptr %ret 86} 87