1; Test that the strncmp library call simplifier works correctly.
2; RUN: opt < %s -instcombine -S | FileCheck %s
3
4target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
5
6@hello = constant [6 x i8] c"hello\00"
7@hell = constant [5 x i8] c"hell\00"
8@bell = constant [5 x i8] c"bell\00"
9@null = constant [1 x i8] zeroinitializer
10
11declare i32 @strncmp(i8*, i8*, i32)
12
13; strncmp("", x, n) -> -*x
14define i32 @test1(i8* %str2) {
15; CHECK-LABEL: @test1(
16; CHECK: %strcmpload = load i8, i8* %str
17; CHECK: %1 = zext i8 %strcmpload to i32
18; CHECK: %2 = sub nsw i32 0, %1
19; CHECK: ret i32 %2
20
21  %str1 = getelementptr inbounds [1 x i8], [1 x i8]* @null, i32 0, i32 0
22  %temp1 = call i32 @strncmp(i8* %str1, i8* %str2, i32 10)
23  ret i32 %temp1
24}
25
26; strncmp(x, "", n) -> *x
27define i32 @test2(i8* %str1) {
28; CHECK-LABEL: @test2(
29; CHECK: %strcmpload = load i8, i8* %str1
30; CHECK: %1 = zext i8 %strcmpload to i32
31; CHECK: ret i32 %1
32
33  %str2 = getelementptr inbounds [1 x i8], [1 x i8]* @null, i32 0, i32 0
34  %temp1 = call i32 @strncmp(i8* %str1, i8* %str2, i32 10)
35  ret i32 %temp1
36}
37
38; strncmp(x, y, n)  -> cnst
39define i32 @test3() {
40; CHECK-LABEL: @test3(
41; CHECK: ret i32 -1
42
43  %str1 = getelementptr inbounds [5 x i8], [5 x i8]* @hell, i32 0, i32 0
44  %str2 = getelementptr inbounds [6 x i8], [6 x i8]* @hello, i32 0, i32 0
45  %temp1 = call i32 @strncmp(i8* %str1, i8* %str2, i32 10)
46  ret i32 %temp1
47}
48
49define i32 @test4() {
50; CHECK-LABEL: @test4(
51; CHECK: ret i32 1
52
53  %str1 = getelementptr inbounds [5 x i8], [5 x i8]* @hell, i32 0, i32 0
54  %str2 = getelementptr inbounds [1 x i8], [1 x i8]* @null, i32 0, i32 0
55  %temp1 = call i32 @strncmp(i8* %str1, i8* %str2, i32 10)
56  ret i32 %temp1
57}
58
59define i32 @test5() {
60; CHECK-LABEL: @test5(
61; CHECK: ret i32 0
62
63  %str1 = getelementptr inbounds [5 x i8], [5 x i8]* @hell, i32 0, i32 0
64  %str2 = getelementptr inbounds [6 x i8], [6 x i8]* @hello, i32 0, i32 0
65  %temp1 = call i32 @strncmp(i8* %str1, i8* %str2, i32 4)
66  ret i32 %temp1
67}
68
69; strncmp(x,y,1) -> memcmp(x,y,1)
70define i32 @test6(i8* %str1, i8* %str2) {
71; CHECK-LABEL: @test6(
72; CHECK: [[LOAD1:%[a-z]+]] = load i8, i8* %str1, align 1
73; CHECK: [[ZEXT1:%[a-z]+]] = zext i8 [[LOAD1]] to i32
74; CHECK: [[LOAD2:%[a-z]+]] = load i8, i8* %str2, align 1
75; CHECK: [[ZEXT2:%[a-z]+]] = zext i8 [[LOAD2]] to i32
76; CHECK: [[RET:%[a-z]+]] = sub nsw i32 [[ZEXT1]], [[ZEXT2]]
77; CHECK: ret i32 [[RET]]
78
79  %temp1 = call i32 @strncmp(i8* %str1, i8* %str2, i32 1)
80  ret i32 %temp1
81}
82
83; strncmp(x,y,0)   -> 0
84define i32 @test7(i8* %str1, i8* %str2) {
85; CHECK-LABEL: @test7(
86; CHECK: ret i32 0
87
88  %temp1 = call i32 @strncmp(i8* %str1, i8* %str2, i32 0)
89  ret i32 %temp1
90}
91
92; strncmp(x,x,n)  -> 0
93define i32 @test8(i8* %str, i32 %n) {
94; CHECK-LABEL: @test8(
95; CHECK: ret i32 0
96
97  %temp1 = call i32 @strncmp(i8* %str, i8* %str, i32 %n)
98  ret i32 %temp1
99}
100