File: memchr-7.ll

package info (click to toggle)
llvm-toolchain-17 1%3A17.0.6-22
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,799,624 kB
  • sloc: cpp: 6,428,607; ansic: 1,383,196; asm: 793,408; python: 223,504; objc: 75,364; f90: 60,502; lisp: 33,869; pascal: 15,282; sh: 9,684; perl: 7,453; ml: 4,937; awk: 3,523; makefile: 2,889; javascript: 2,149; xml: 888; fortran: 619; cs: 573
file content (154 lines) | stat: -rw-r--r-- 6,093 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -passes=instcombine -instcombine-infinite-loop-threshold=2 -S | FileCheck %s

@.str = private unnamed_addr constant [27 x i8] c"abcdefghijklmnopqrstuvwxyz\00", align 1
@.str.1 = private unnamed_addr constant [2 x i8] c"\0D\0A", align 1
@.str.2 = private unnamed_addr constant [10 x i8] c"abcdefmno\00", align 1
@.str.3 = private unnamed_addr constant [10 x i8] c"abcijkmno\00", align 1
@.str.4 = private unnamed_addr constant [7 x i8] c"mnabcc\00", align 1

declare ptr @strchr(ptr, i32)
declare ptr @memchr(ptr, i32, i64)

define zeroext i1 @strchr_to_memchr_n_equals_len(i32 %c) {
; CHECK-LABEL: @strchr_to_memchr_n_equals_len(
; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[C:%.*]], 0
; CHECK-NEXT:    [[TMP2:%.*]] = add i32 [[C]], -97
; CHECK-NEXT:    [[TMP3:%.*]] = icmp ult i32 [[TMP2]], 26
; CHECK-NEXT:    [[TMP4:%.*]] = or i1 [[TMP1]], [[TMP3]]
; CHECK-NEXT:    ret i1 [[TMP4]]
;
  %call = tail call ptr @strchr(ptr nonnull dereferenceable(27) @.str, i32 %c)
  %cmp = icmp ne ptr %call, null
  ret i1 %cmp
}

define zeroext i1 @memchr_n_equals_len(i32 %c) {
; CHECK-LABEL: @memchr_n_equals_len(
; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[C:%.*]] to i8
; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i8 [[TMP1]], 10
; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i8 [[TMP1]], 13
; CHECK-NEXT:    [[CMP:%.*]] = and i1 [[TMP3]], [[TMP2]]
; CHECK-NEXT:    ret i1 [[CMP]]
;
  %call = tail call ptr @memchr(ptr nonnull dereferenceable(3) @.str.1, i32 %c, i64 2)
  %cmp = icmp eq ptr %call, null
  ret i1 %cmp
}

define zeroext i1 @memchr_n_less_than_len(i32 %c) {
; CHECK-LABEL: @memchr_n_less_than_len(
; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[C:%.*]], -97
; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 [[TMP1]], 15
; CHECK-NEXT:    ret i1 [[TMP2]]
;
  %call = tail call ptr @memchr(ptr @.str, i32 %c, i64 15)
  %cmp = icmp ne ptr %call, null
  ret i1 %cmp
}


define zeroext i1 @memchr_n_more_than_len(i32 %c) {
; CHECK-LABEL: @memchr_n_more_than_len(
; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[C:%.*]], 0
; CHECK-NEXT:    [[TMP2:%.*]] = add i32 [[C]], -97
; CHECK-NEXT:    [[TMP3:%.*]] = icmp ult i32 [[TMP2]], 26
; CHECK-NEXT:    [[TMP4:%.*]] = or i1 [[TMP1]], [[TMP3]]
; CHECK-NEXT:    ret i1 [[TMP4]]
;
  %call = tail call ptr @memchr(ptr @.str, i32 %c, i64 30)
  %cmp = icmp ne ptr %call, null
  ret i1 %cmp
}

; Negative test - no comparison with zero

define ptr @memchr_no_zero_cmp(i32 %c) {
; CHECK-LABEL: @memchr_no_zero_cmp(
; CHECK-NEXT:    [[MEMCHR:%.*]] = tail call ptr @memchr(ptr noundef nonnull dereferenceable(1) @.str, i32 [[C:%.*]], i64 27)
; CHECK-NEXT:    ret ptr [[MEMCHR]]
;
  %call = tail call ptr @strchr(ptr nonnull dereferenceable(27) @.str, i32 %c)
  ret ptr %call
}

define ptr @memchr_no_zero_cmp2(i32 %c) {
; CHECK-LABEL: @memchr_no_zero_cmp2(
; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[C:%.*]] to i8
; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i8 [[TMP1]], 10
; CHECK-NEXT:    [[MEMCHR_SEL1:%.*]] = select i1 [[TMP2]], ptr getelementptr inbounds ([2 x i8], ptr @.str.1, i64 0, i64 1), ptr null
; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i8 [[TMP1]], 13
; CHECK-NEXT:    [[MEMCHR_SEL2:%.*]] = select i1 [[TMP3]], ptr @.str.1, ptr [[MEMCHR_SEL1]]
; CHECK-NEXT:    ret ptr [[MEMCHR_SEL2]]
;
  %call = tail call ptr @strchr(ptr nonnull dereferenceable(3) @.str.1, i32 %c)
  ret ptr %call
}

; Negative test - opt for size

define zeroext i1 @memchr_n_equals_len_minsize(i32 %c) minsize {
; CHECK-LABEL: @memchr_n_equals_len_minsize(
; CHECK-NEXT:    [[MEMCHR:%.*]] = tail call ptr @memchr(ptr noundef nonnull dereferenceable(1) @.str, i32 [[C:%.*]], i64 27)
; CHECK-NEXT:    [[CMP:%.*]] = icmp ne ptr [[MEMCHR]], null
; CHECK-NEXT:    ret i1 [[CMP]]
;
  %call = tail call ptr @strchr(ptr nonnull dereferenceable(27) @.str, i32 %c)
  %cmp = icmp ne ptr %call, null
  ret i1 %cmp
}

define zeroext i1 @memchr_n_equals_len2_minsize(i32 %c) minsize {
; CHECK-LABEL: @memchr_n_equals_len2_minsize(
; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[C:%.*]] to i8
; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i8 [[TMP1]], 10
; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i8 [[TMP1]], 13
; CHECK-NEXT:    [[CMP:%.*]] = and i1 [[TMP3]], [[TMP2]]
; CHECK-NEXT:    ret i1 [[CMP]]
;
  %call = tail call ptr @memchr(ptr nonnull dereferenceable(3) @.str.1, i32 %c, i64 2)
  %cmp = icmp eq ptr %call, null
  ret i1 %cmp
}

; Positive test - 2 non-contiguous ranges
define zeroext i1 @strchr_to_memchr_2_non_cont_ranges(i32 %c) {
; CHECK-LABEL: @strchr_to_memchr_2_non_cont_ranges(
; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[C:%.*]], -97
; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 [[TMP1]], 6
; CHECK-NEXT:    [[TMP3:%.*]] = add i32 [[C]], -109
; CHECK-NEXT:    [[TMP4:%.*]] = icmp ult i32 [[TMP3]], 3
; CHECK-NEXT:    [[TMP5:%.*]] = or i1 [[TMP2]], [[TMP4]]
; CHECK-NEXT:    ret i1 [[TMP5]]
;
  %call = tail call ptr @memchr(ptr @.str.2, i32 %c, i64 9)
  %cmp = icmp ne ptr %call, null
  ret i1 %cmp
}

; Positive test - 2 non-contiguous ranges with char duplication
define zeroext i1 @strchr_to_memchr_2_non_cont_ranges_char_dup(i32 %c) {
; CHECK-LABEL: @strchr_to_memchr_2_non_cont_ranges_char_dup(
; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[C:%.*]], -97
; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 [[TMP1]], 3
; CHECK-NEXT:    [[TMP3:%.*]] = add i32 [[C]], -109
; CHECK-NEXT:    [[TMP4:%.*]] = icmp ult i32 [[TMP3]], 2
; CHECK-NEXT:    [[TMP5:%.*]] = or i1 [[TMP2]], [[TMP4]]
; CHECK-NEXT:    ret i1 [[TMP5]]
;
  %call = tail call ptr @memchr(ptr @.str.4, i32 %c, i64 6)
  %cmp = icmp ne ptr %call, null
  ret i1 %cmp
}

; Negative test - more than 2 non-contiguous ranges
define zeroext i1 @strchr_to_memchr_3_non_cont_ranges(i32 %c) {
; CHECK-LABEL: @strchr_to_memchr_3_non_cont_ranges(
; CHECK-NEXT:    [[CALL:%.*]] = tail call ptr @memchr(ptr noundef nonnull dereferenceable(1) @.str.3, i32 [[C:%.*]], i64 9)
; CHECK-NEXT:    [[CMP:%.*]] = icmp ne ptr [[CALL]], null
; CHECK-NEXT:    ret i1 [[CMP]]
;
  %call = tail call ptr @memchr(ptr @.str.3, i32 %c, i64 9)
  %cmp = icmp ne ptr %call, null
  ret i1 %cmp
}