1; Test that the strcmp library call simplifier works correctly. 2; RUN: opt < %s -instcombine -S | FileCheck %s 3 4target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64" 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 @strcmp(i8*, i8*) 12 13; strcmp("", x) -> -*x 14define arm_aapcscc 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 arm_apcscc i32 @strcmp(i8* %str1, i8* %str2) 23 ret i32 %temp1 24 25} 26 27; strcmp(x, "") -> *x 28define arm_aapcscc i32 @test2(i8* %str1) { 29; CHECK-LABEL: @test2( 30; CHECK: %strcmpload = load i8, i8* %str 31; CHECK: %1 = zext i8 %strcmpload to i32 32; CHECK: ret i32 %1 33 34 %str2 = getelementptr inbounds [1 x i8], [1 x i8]* @null, i32 0, i32 0 35 %temp1 = call arm_aapcscc i32 @strcmp(i8* %str1, i8* %str2) 36 ret i32 %temp1 37} 38 39; strcmp(x, y) -> cnst 40define arm_aapcscc i32 @test3() { 41; CHECK-LABEL: @test3( 42; CHECK: ret i32 -1 43 44 %str1 = getelementptr inbounds [5 x i8], [5 x i8]* @hell, i32 0, i32 0 45 %str2 = getelementptr inbounds [6 x i8], [6 x i8]* @hello, i32 0, i32 0 46 %temp1 = call arm_aapcscc i32 @strcmp(i8* %str1, i8* %str2) 47 ret i32 %temp1 48} 49 50define arm_aapcscc i32 @test4() { 51; CHECK-LABEL: @test4( 52; CHECK: ret i32 1 53 54 %str1 = getelementptr inbounds [5 x i8], [5 x i8]* @hell, i32 0, i32 0 55 %str2 = getelementptr inbounds [1 x i8], [1 x i8]* @null, i32 0, i32 0 56 %temp1 = call arm_aapcscc i32 @strcmp(i8* %str1, i8* %str2) 57 ret i32 %temp1 58} 59 60; strcmp(x, y) -> memcmp(x, y, <known length>) 61; (This transform is rather difficult to trigger in a useful manner) 62define arm_aapcscc i32 @test5(i1 %b) { 63; CHECK-LABEL: @test5( 64; CHECK: %memcmp = call i32 @memcmp(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i32 0, i32 0), i8* %str2, i32 5) 65; CHECK: ret i32 %memcmp 66 67 %str1 = getelementptr inbounds [6 x i8], [6 x i8]* @hello, i32 0, i32 0 68 %temp1 = getelementptr inbounds [5 x i8], [5 x i8]* @hell, i32 0, i32 0 69 %temp2 = getelementptr inbounds [5 x i8], [5 x i8]* @bell, i32 0, i32 0 70 %str2 = select i1 %b, i8* %temp1, i8* %temp2 71 %temp3 = call arm_aapcscc i32 @strcmp(i8* %str1, i8* %str2) 72 ret i32 %temp3 73} 74 75; strcmp(x,x) -> 0 76define arm_aapcscc i32 @test6(i8* %str) { 77; CHECK-LABEL: @test6( 78; CHECK: ret i32 0 79 80 %temp1 = call arm_aapcscc i32 @strcmp(i8* %str, i8* %str) 81 ret i32 %temp1 82} 83 84; strcmp("", x) -> -*x 85define arm_aapcs_vfpcc i32 @test1_vfp(i8* %str2) { 86; CHECK-LABEL: @test1_vfp( 87; CHECK: %strcmpload = load i8, i8* %str 88; CHECK: %1 = zext i8 %strcmpload to i32 89; CHECK: %2 = sub nsw i32 0, %1 90; CHECK: ret i32 %2 91 92 %str1 = getelementptr inbounds [1 x i8], [1 x i8]* @null, i32 0, i32 0 93 %temp1 = call arm_aapcs_vfpcc i32 @strcmp(i8* %str1, i8* %str2) 94 ret i32 %temp1 95 96} 97 98; strcmp(x, "") -> *x 99define arm_aapcs_vfpcc i32 @test2_vfp(i8* %str1) { 100; CHECK-LABEL: @test2_vfp( 101; CHECK: %strcmpload = load i8, i8* %str 102; CHECK: %1 = zext i8 %strcmpload to i32 103; CHECK: ret i32 %1 104 105 %str2 = getelementptr inbounds [1 x i8], [1 x i8]* @null, i32 0, i32 0 106 %temp1 = call arm_aapcs_vfpcc i32 @strcmp(i8* %str1, i8* %str2) 107 ret i32 %temp1 108} 109 110; strcmp(x, y) -> cnst 111define arm_aapcs_vfpcc i32 @test3_vfp() { 112; CHECK-LABEL: @test3_vfp( 113; CHECK: ret i32 -1 114 115 %str1 = getelementptr inbounds [5 x i8], [5 x i8]* @hell, i32 0, i32 0 116 %str2 = getelementptr inbounds [6 x i8], [6 x i8]* @hello, i32 0, i32 0 117 %temp1 = call arm_aapcs_vfpcc i32 @strcmp(i8* %str1, i8* %str2) 118 ret i32 %temp1 119} 120 121define arm_aapcs_vfpcc i32 @test4_vfp() { 122; CHECK-LABEL: @test4_vfp( 123; CHECK: ret i32 1 124 125 %str1 = getelementptr inbounds [5 x i8], [5 x i8]* @hell, i32 0, i32 0 126 %str2 = getelementptr inbounds [1 x i8], [1 x i8]* @null, i32 0, i32 0 127 %temp1 = call arm_aapcs_vfpcc i32 @strcmp(i8* %str1, i8* %str2) 128 ret i32 %temp1 129} 130 131; strcmp(x, y) -> memcmp(x, y, <known length>) 132; (This transform is rather difficult to trigger in a useful manner) 133define arm_aapcs_vfpcc i32 @test5_vfp(i1 %b) { 134; CHECK-LABEL: @test5_vfp( 135; CHECK: %memcmp = call i32 @memcmp(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i32 0, i32 0), i8* %str2, i32 5) 136; CHECK: ret i32 %memcmp 137 138 %str1 = getelementptr inbounds [6 x i8], [6 x i8]* @hello, i32 0, i32 0 139 %temp1 = getelementptr inbounds [5 x i8], [5 x i8]* @hell, i32 0, i32 0 140 %temp2 = getelementptr inbounds [5 x i8], [5 x i8]* @bell, i32 0, i32 0 141 %str2 = select i1 %b, i8* %temp1, i8* %temp2 142 %temp3 = call arm_aapcs_vfpcc i32 @strcmp(i8* %str1, i8* %str2) 143 ret i32 %temp3 144} 145 146; strcmp(x,x) -> 0 147define arm_aapcs_vfpcc i32 @test6_vfp(i8* %str) { 148; CHECK-LABEL: @test6_vfp( 149; CHECK: ret i32 0 150 151 %temp1 = call arm_aapcs_vfpcc i32 @strcmp(i8* %str, i8* %str) 152 ret i32 %temp1 153} 154