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 -passes=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(ptr, ptr) 13 14; strcmp("", x) -> -*x 15define arm_aapcscc i32 @test1(ptr %str2) { 16; CHECK-LABEL: @test1( 17; CHECK-NEXT: [[STRCMPLOAD:%.*]] = load i8, ptr [[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 %temp1 = call arm_apcscc i32 @strcmp(ptr @null, ptr %str2) 24 ret i32 %temp1 25 26} 27 28; strcmp(x, "") -> *x 29define arm_aapcscc i32 @test2(ptr %str1) { 30; CHECK-LABEL: @test2( 31; CHECK-NEXT: [[STRCMPLOAD:%.*]] = load i8, ptr [[STR1:%.*]], align 1 32; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[STRCMPLOAD]] to i32 33; CHECK-NEXT: ret i32 [[TMP1]] 34; 35 36 %temp1 = call arm_aapcscc i32 @strcmp(ptr %str1, ptr @null) 37 ret i32 %temp1 38} 39 40; strcmp(x, y) -> cnst 41define arm_aapcscc i32 @test3() { 42; CHECK-LABEL: @test3( 43; CHECK-NEXT: ret i32 -1 44; 45 46 %temp1 = call arm_aapcscc i32 @strcmp(ptr @hell, ptr @hello) 47 ret i32 %temp1 48} 49 50define arm_aapcscc i32 @test4() { 51; CHECK-LABEL: @test4( 52; CHECK-NEXT: ret i32 1 53; 54 55 %temp1 = call arm_aapcscc i32 @strcmp(ptr @hell, ptr @null) 56 ret i32 %temp1 57} 58 59; strcmp(x, y) -> memcmp(x, y, <known length>) 60; (This transform is rather difficult to trigger in a useful manner) 61define arm_aapcscc i32 @test5(i1 %b) { 62; CHECK-LABEL: @test5( 63; CHECK-NEXT: [[STR2:%.*]] = select i1 [[B:%.*]], ptr @hell, ptr @bell 64; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(ptr noundef nonnull dereferenceable(5) @hello, ptr noundef nonnull dereferenceable(5) [[STR2]], i32 5) 65; CHECK-NEXT: ret i32 [[MEMCMP]] 66; 67 68 %str2 = select i1 %b, ptr @hell, ptr @bell 69 %temp3 = call arm_aapcscc i32 @strcmp(ptr @hello, ptr %str2) 70 ret i32 %temp3 71} 72 73; strcmp(x,x) -> 0 74define arm_aapcscc i32 @test6(ptr %str) { 75; CHECK-LABEL: @test6( 76; CHECK-NEXT: ret i32 0 77; 78 79 %temp1 = call arm_aapcscc i32 @strcmp(ptr %str, ptr %str) 80 ret i32 %temp1 81} 82 83; strcmp("", x) -> -*x 84define arm_aapcs_vfpcc i32 @test1_vfp(ptr %str2) { 85; CHECK-LABEL: @test1_vfp( 86; CHECK-NEXT: [[STRCMPLOAD:%.*]] = load i8, ptr [[STR2:%.*]], align 1 87; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[STRCMPLOAD]] to i32 88; CHECK-NEXT: [[TMP2:%.*]] = sub nsw i32 0, [[TMP1]] 89; CHECK-NEXT: ret i32 [[TMP2]] 90; 91 92 %temp1 = call arm_aapcs_vfpcc i32 @strcmp(ptr @null, ptr %str2) 93 ret i32 %temp1 94 95} 96 97; strcmp(x, "") -> *x 98define arm_aapcs_vfpcc i32 @test2_vfp(ptr %str1) { 99; CHECK-LABEL: @test2_vfp( 100; CHECK-NEXT: [[STRCMPLOAD:%.*]] = load i8, ptr [[STR1:%.*]], align 1 101; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[STRCMPLOAD]] to i32 102; CHECK-NEXT: ret i32 [[TMP1]] 103; 104 105 %temp1 = call arm_aapcs_vfpcc i32 @strcmp(ptr %str1, ptr @null) 106 ret i32 %temp1 107} 108 109; strcmp(x, y) -> cnst 110define arm_aapcs_vfpcc i32 @test3_vfp() { 111; CHECK-LABEL: @test3_vfp( 112; CHECK-NEXT: ret i32 -1 113; 114 115 %temp1 = call arm_aapcs_vfpcc i32 @strcmp(ptr @hell, ptr @hello) 116 ret i32 %temp1 117} 118 119define arm_aapcs_vfpcc i32 @test4_vfp() { 120; CHECK-LABEL: @test4_vfp( 121; CHECK-NEXT: ret i32 1 122; 123 124 %temp1 = call arm_aapcs_vfpcc i32 @strcmp(ptr @hell, ptr @null) 125 ret i32 %temp1 126} 127 128; strcmp(x, y) -> memcmp(x, y, <known length>) 129; (This transform is rather difficult to trigger in a useful manner) 130define arm_aapcs_vfpcc i32 @test5_vfp(i1 %b) { 131; CHECK-LABEL: @test5_vfp( 132; CHECK-NEXT: [[STR2:%.*]] = select i1 [[B:%.*]], ptr @hell, ptr @bell 133; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(ptr noundef nonnull dereferenceable(5) @hello, ptr noundef nonnull dereferenceable(5) [[STR2]], i32 5) 134; CHECK-NEXT: ret i32 [[MEMCMP]] 135; 136 137 %str2 = select i1 %b, ptr @hell, ptr @bell 138 %temp3 = call arm_aapcs_vfpcc i32 @strcmp(ptr @hello, ptr %str2) 139 ret i32 %temp3 140} 141 142; strcmp(x,x) -> 0 143define arm_aapcs_vfpcc i32 @test6_vfp(ptr %str) { 144; CHECK-LABEL: @test6_vfp( 145; CHECK-NEXT: ret i32 0 146; 147 148 %temp1 = call arm_aapcs_vfpcc i32 @strcmp(ptr %str, ptr %str) 149 ret i32 %temp1 150} 151