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