1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; Test that the strlen library call simplifier works correctly. 3; 4; RUN: opt < %s -instcombine -S | FileCheck %s 5 6target 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" 7 8@hello = constant [6 x i8] c"hello\00" 9@longer = constant [7 x i8] c"longer\00" 10@null = constant [1 x i8] zeroinitializer 11@null_hello = constant [7 x i8] c"\00hello\00" 12@nullstring = constant i8 0 13@a = common global [32 x i8] zeroinitializer, align 1 14@null_hello_mid = constant [13 x i8] c"hello wor\00ld\00" 15 16declare i32 @strlen(i8*) 17 18; Check strlen(string constant) -> integer constant. 19 20define i32 @test_simplify1() { 21; CHECK-LABEL: @test_simplify1( 22; CHECK-NEXT: ret i32 5 23; 24 %hello_p = getelementptr [6 x i8], [6 x i8]* @hello, i32 0, i32 0 25 %hello_l = call i32 @strlen(i8* %hello_p) 26 ret i32 %hello_l 27} 28 29define i32 @test_simplify2() { 30; CHECK-LABEL: @test_simplify2( 31; CHECK-NEXT: ret i32 0 32; 33 %null_p = getelementptr [1 x i8], [1 x i8]* @null, i32 0, i32 0 34 %null_l = call i32 @strlen(i8* %null_p) 35 ret i32 %null_l 36} 37 38define i32 @test_simplify3() { 39; CHECK-LABEL: @test_simplify3( 40; CHECK-NEXT: ret i32 0 41; 42 %null_hello_p = getelementptr [7 x i8], [7 x i8]* @null_hello, i32 0, i32 0 43 %null_hello_l = call i32 @strlen(i8* %null_hello_p) 44 ret i32 %null_hello_l 45} 46 47define i32 @test_simplify4() { 48; CHECK-LABEL: @test_simplify4( 49; CHECK-NEXT: ret i32 0 50; 51 %len = tail call i32 @strlen(i8* @nullstring) nounwind 52 ret i32 %len 53} 54 55; Check strlen(x) == 0 --> *x == 0. 56 57define i1 @test_simplify5() { 58; CHECK-LABEL: @test_simplify5( 59; CHECK-NEXT: ret i1 false 60; 61 %hello_p = getelementptr [6 x i8], [6 x i8]* @hello, i32 0, i32 0 62 %hello_l = call i32 @strlen(i8* %hello_p) 63 %eq_hello = icmp eq i32 %hello_l, 0 64 ret i1 %eq_hello 65} 66 67define i1 @test_simplify6() { 68; CHECK-LABEL: @test_simplify6( 69; CHECK-NEXT: ret i1 true 70; 71 %null_p = getelementptr [1 x i8], [1 x i8]* @null, i32 0, i32 0 72 %null_l = call i32 @strlen(i8* %null_p) 73 %eq_null = icmp eq i32 %null_l, 0 74 ret i1 %eq_null 75} 76 77; Check strlen(x) != 0 --> *x != 0. 78 79define i1 @test_simplify7() { 80; CHECK-LABEL: @test_simplify7( 81; CHECK-NEXT: ret i1 true 82; 83 %hello_p = getelementptr [6 x i8], [6 x i8]* @hello, i32 0, i32 0 84 %hello_l = call i32 @strlen(i8* %hello_p) 85 %ne_hello = icmp ne i32 %hello_l, 0 86 ret i1 %ne_hello 87} 88 89define i1 @test_simplify8() { 90; CHECK-LABEL: @test_simplify8( 91; CHECK-NEXT: ret i1 false 92; 93 %null_p = getelementptr [1 x i8], [1 x i8]* @null, i32 0, i32 0 94 %null_l = call i32 @strlen(i8* %null_p) 95 %ne_null = icmp ne i32 %null_l, 0 96 ret i1 %ne_null 97} 98 99define i32 @test_simplify9(i1 %x) { 100; CHECK-LABEL: @test_simplify9( 101; CHECK-NEXT: [[TMP1:%.*]] = select i1 %x, i32 5, i32 6 102; CHECK-NEXT: ret i32 [[TMP1]] 103; 104 %hello = getelementptr [6 x i8], [6 x i8]* @hello, i32 0, i32 0 105 %longer = getelementptr [7 x i8], [7 x i8]* @longer, i32 0, i32 0 106 %s = select i1 %x, i8* %hello, i8* %longer 107 %l = call i32 @strlen(i8* %s) 108 ret i32 %l 109} 110 111; Check the case that should be simplified to a sub instruction. 112; strlen(@hello + x) --> 5 - x 113 114define i32 @test_simplify10(i32 %x) { 115; CHECK-LABEL: @test_simplify10( 116; CHECK-NEXT: [[TMP1:%.*]] = sub i32 5, %x 117; CHECK-NEXT: ret i32 [[TMP1]] 118; 119 %hello_p = getelementptr inbounds [6 x i8], [6 x i8]* @hello, i32 0, i32 %x 120 %hello_l = call i32 @strlen(i8* %hello_p) 121 ret i32 %hello_l 122} 123 124; strlen(@null_hello_mid + (x & 7)) --> 9 - (x & 7) 125 126define i32 @test_simplify11(i32 %x) { 127; CHECK-LABEL: @test_simplify11( 128; CHECK-NEXT: [[AND:%.*]] = and i32 %x, 7 129; CHECK-NEXT: [[TMP1:%.*]] = sub nsw i32 9, [[AND]] 130; CHECK-NEXT: ret i32 [[TMP1]] 131; 132 %and = and i32 %x, 7 133 %hello_p = getelementptr inbounds [13 x i8], [13 x i8]* @null_hello_mid, i32 0, i32 %and 134 %hello_l = call i32 @strlen(i8* %hello_p) 135 ret i32 %hello_l 136} 137 138; Check cases that shouldn't be simplified. 139 140define i32 @test_no_simplify1() { 141; CHECK-LABEL: @test_no_simplify1( 142; CHECK-NEXT: [[A_L:%.*]] = call i32 @strlen(i8* getelementptr inbounds ([32 x i8], [32 x i8]* @a, i32 0, i32 0)) 143; CHECK-NEXT: ret i32 [[A_L]] 144; 145 %a_p = getelementptr [32 x i8], [32 x i8]* @a, i32 0, i32 0 146 %a_l = call i32 @strlen(i8* %a_p) 147 ret i32 %a_l 148} 149 150; strlen(@null_hello + x) should not be simplified to a sub instruction. 151 152define i32 @test_no_simplify2(i32 %x) { 153; CHECK-LABEL: @test_no_simplify2( 154; CHECK-NEXT: [[HELLO_P:%.*]] = getelementptr inbounds [7 x i8], [7 x i8]* @null_hello, i32 0, i32 %x 155; CHECK-NEXT: [[HELLO_L:%.*]] = call i32 @strlen(i8* [[HELLO_P]]) 156; CHECK-NEXT: ret i32 [[HELLO_L]] 157; 158 %hello_p = getelementptr inbounds [7 x i8], [7 x i8]* @null_hello, i32 0, i32 %x 159 %hello_l = call i32 @strlen(i8* %hello_p) 160 ret i32 %hello_l 161} 162 163; strlen(@null_hello_mid + (x & 15)) should not be simplified to a sub instruction. 164 165define i32 @test_no_simplify3(i32 %x) { 166; CHECK-LABEL: @test_no_simplify3( 167; CHECK-NEXT: [[AND:%.*]] = and i32 %x, 15 168; CHECK-NEXT: [[HELLO_P:%.*]] = getelementptr inbounds [13 x i8], [13 x i8]* @null_hello_mid, i32 0, i32 [[AND]] 169; CHECK-NEXT: [[HELLO_L:%.*]] = call i32 @strlen(i8* [[HELLO_P]]) 170; CHECK-NEXT: ret i32 [[HELLO_L]] 171; 172 %and = and i32 %x, 15 173 %hello_p = getelementptr inbounds [13 x i8], [13 x i8]* @null_hello_mid, i32 0, i32 %and 174 %hello_l = call i32 @strlen(i8* %hello_p) 175 ret i32 %hello_l 176} 177 178