xref: /llvm-project/llvm/test/Transforms/InstCombine/strstr-1.ll (revision f226cabbb1b9737676536bc4417336bef4808992)
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