xref: /llvm-project/llvm/test/Transforms/InstCombine/wcslen-3.ll (revision 23a239267e8a1d20ed10d3545feaf2a2bb70b085)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; Test that the wcslen library call simplifier works correctly.
3;
4; RUN: opt < %s -passes=instcombine -S | FileCheck %s
5
6target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
7
8; Test behavior for wchar_size==2
9!llvm.module.flags = !{!0}
10!0 = !{i32 1, !"wchar_size", i32 2}
11
12declare i64 @wcslen(ptr)
13
14@hello = constant [6 x i16] [i16 104, i16 101, i16 108, i16 108, i16 111, i16 0]
15@longer = constant [7 x i16] [i16 108, i16 111, i16 110, i16 103, i16 101, i16 114, i16 0]
16@null = constant [1 x i16] zeroinitializer
17@null_hello = constant [7 x i16] [i16 0, i16 104, i16 101, i16 108, i16 108, i16 111, i16 0]
18@nullstring = constant i16 0
19@a = common global [32 x i16] zeroinitializer, align 1
20@null_hello_mid = constant [13 x i16] [i16 104, i16 101, i16 108, i16 108, i16 111, i16 32, i16 119, i16 111, i16 114, i16 0, i16 108, i16 100, i16 0]
21
22define i64 @test_simplify1() {
23; CHECK-LABEL: @test_simplify1(
24; CHECK-NEXT:    ret i64 5
25;
26  %hello_l = call i64 @wcslen(ptr @hello)
27  ret i64 %hello_l
28}
29
30define i64 @test_simplify2() {
31; CHECK-LABEL: @test_simplify2(
32; CHECK-NEXT:    ret i64 0
33;
34  %null_l = call i64 @wcslen(ptr @null)
35  ret i64 %null_l
36}
37
38define i64 @test_simplify3() {
39; CHECK-LABEL: @test_simplify3(
40; CHECK-NEXT:    ret i64 0
41;
42  %null_hello_l = call i64 @wcslen(ptr @null_hello)
43  ret i64 %null_hello_l
44}
45
46define i64 @test_simplify4() {
47; CHECK-LABEL: @test_simplify4(
48; CHECK-NEXT:    ret i64 0
49;
50  %len = tail call i64 @wcslen(ptr @nullstring) nounwind
51  ret i64 %len
52}
53
54; Check wcslen(x) == 0 --> *x == 0.
55
56define i1 @test_simplify5() {
57; CHECK-LABEL: @test_simplify5(
58; CHECK-NEXT:    ret i1 false
59;
60  %hello_l = call i64 @wcslen(ptr @hello)
61  %eq_hello = icmp eq i64 %hello_l, 0
62  ret i1 %eq_hello
63}
64
65define i1 @test_simplify6(ptr %str_p) {
66; CHECK-LABEL: @test_simplify6(
67; CHECK-NEXT:    [[CHAR0:%.*]] = load i16, ptr [[STR_P:%.*]], align 2
68; CHECK-NEXT:    [[EQ_NULL:%.*]] = icmp eq i16 [[CHAR0]], 0
69; CHECK-NEXT:    ret i1 [[EQ_NULL]]
70;
71  %str_l = call i64 @wcslen(ptr %str_p)
72  %eq_null = icmp eq i64 %str_l, 0
73  ret i1 %eq_null
74}
75
76; Check wcslen(x) != 0 --> *x != 0.
77
78define i1 @test_simplify7() {
79; CHECK-LABEL: @test_simplify7(
80; CHECK-NEXT:    ret i1 true
81;
82  %hello_l = call i64 @wcslen(ptr @hello)
83  %ne_hello = icmp ne i64 %hello_l, 0
84  ret i1 %ne_hello
85}
86
87define i1 @test_simplify8(ptr %str_p) {
88; CHECK-LABEL: @test_simplify8(
89; CHECK-NEXT:    [[CHAR0:%.*]] = load i16, ptr [[STR_P:%.*]], align 2
90; CHECK-NEXT:    [[NE_NULL:%.*]] = icmp ne i16 [[CHAR0]], 0
91; CHECK-NEXT:    ret i1 [[NE_NULL]]
92;
93  %str_l = call i64 @wcslen(ptr %str_p)
94  %ne_null = icmp ne i64 %str_l, 0
95  ret i1 %ne_null
96}
97
98define i64 @test_simplify9(i1 %x) {
99; CHECK-LABEL: @test_simplify9(
100; CHECK-NEXT:    [[L:%.*]] = select i1 [[X:%.*]], i64 5, i64 6
101; CHECK-NEXT:    ret i64 [[L]]
102;
103  %s = select i1 %x, ptr @hello, ptr @longer
104  %l = call i64 @wcslen(ptr %s)
105  ret i64 %l
106}
107
108; Check the case that should be simplified to a sub instruction.
109; wcslen(@hello + x) --> 5 - x
110
111define i64 @test_simplify10(i16 %x) {
112; CHECK-LABEL: @test_simplify10(
113; CHECK-NEXT:    [[TMP1:%.*]] = sext i16 [[X:%.*]] to i64
114; CHECK-NEXT:    [[HELLO_L:%.*]] = sub nsw i64 5, [[TMP1]]
115; CHECK-NEXT:    ret i64 [[HELLO_L]]
116;
117  %hello_p = getelementptr inbounds [6 x i16], ptr @hello, i16 0, i16 %x
118  %hello_l = call i64 @wcslen(ptr %hello_p)
119  ret i64 %hello_l
120}
121
122; wcslen(@null_hello_mid + (x & 7)) --> 9 - (x & 7)
123
124define i64 @test_simplify11(i16 %x) {
125; CHECK-LABEL: @test_simplify11(
126; CHECK-NEXT:    [[AND:%.*]] = and i16 [[X:%.*]], 7
127; CHECK-NEXT:    [[NARROW:%.*]] = sub nuw nsw i16 9, [[AND]]
128; CHECK-NEXT:    [[HELLO_L:%.*]] = zext nneg i16 [[NARROW]] to i64
129; CHECK-NEXT:    ret i64 [[HELLO_L]]
130;
131  %and = and i16 %x, 7
132  %hello_p = getelementptr inbounds [13 x i16], ptr @null_hello_mid, i16 0, i16 %and
133  %hello_l = call i64 @wcslen(ptr %hello_p)
134  ret i64 %hello_l
135}
136
137; Check cases that shouldn't be simplified.
138
139define i64 @test_no_simplify1() {
140; CHECK-LABEL: @test_no_simplify1(
141; CHECK-NEXT:    [[A_L:%.*]] = call i64 @wcslen(ptr nonnull @a)
142; CHECK-NEXT:    ret i64 [[A_L]]
143;
144  %a_l = call i64 @wcslen(ptr @a)
145  ret i64 %a_l
146}
147
148; wcslen(@null_hello + x) should not be simplified to a sub instruction.
149
150define i64 @test_no_simplify2(i16 %x) {
151; CHECK-LABEL: @test_no_simplify2(
152; CHECK-NEXT:    [[TMP1:%.*]] = sext i16 [[X:%.*]] to i64
153; CHECK-NEXT:    [[HELLO_P:%.*]] = getelementptr inbounds [7 x i16], ptr @null_hello, i64 0, i64 [[TMP1]]
154; CHECK-NEXT:    [[HELLO_L:%.*]] = call i64 @wcslen(ptr nonnull [[HELLO_P]])
155; CHECK-NEXT:    ret i64 [[HELLO_L]]
156;
157  %hello_p = getelementptr inbounds [7 x i16], ptr @null_hello, i16 0, i16 %x
158  %hello_l = call i64 @wcslen(ptr %hello_p)
159  ret i64 %hello_l
160}
161
162; wcslen(@null_hello_mid + (x & 15)) should not be simplified to a sub instruction.
163
164define i64 @test_no_simplify3(i16 %x) {
165; CHECK-LABEL: @test_no_simplify3(
166; CHECK-NEXT:    [[AND:%.*]] = and i16 [[X:%.*]], 15
167; CHECK-NEXT:    [[TMP1:%.*]] = zext nneg i16 [[AND]] to i64
168; CHECK-NEXT:    [[HELLO_P:%.*]] = getelementptr inbounds nuw [13 x i16], ptr @null_hello_mid, i64 0, i64 [[TMP1]]
169; CHECK-NEXT:    [[HELLO_L:%.*]] = call i64 @wcslen(ptr nonnull [[HELLO_P]])
170; CHECK-NEXT:    ret i64 [[HELLO_L]]
171;
172  %and = and i16 %x, 15
173  %hello_p = getelementptr inbounds [13 x i16], ptr @null_hello_mid, i16 0, i16 %and
174  %hello_l = call i64 @wcslen(ptr %hello_p)
175  ret i64 %hello_l
176}
177
178@str32 = constant [1 x i32] [i32 0]
179
180; This is safe to simplify despite the type mismatch.
181
182define i64 @test_no_simplify4() {
183; CHECK-LABEL: @test_no_simplify4(
184; CHECK-NEXT:    ret i64 0
185;
186  %l = call i64 @wcslen(ptr @str32)
187  ret i64 %l
188}
189