1 ; Test that the strcmp library call simplifier works correctly. 2 ; RUN: opt < %s -instcombine -S | FileCheck %s 3 4 target 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 11 declare i32 @strcmp(i8*, i8*) 12 13 ; strcmp("", x) -> -*x 14 define 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 @strcmp(i8* %str1, i8* %str2) 23 ret i32 %temp1 24 25 } 26 27 ; strcmp(x, "") -> *x 28 define 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 i32 @strcmp(i8* %str1, i8* %str2) 36 ret i32 %temp1 37 } 38 39 ; strcmp(x, y) -> cnst 40 define 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 i32 @strcmp(i8* %str1, i8* %str2) 47 ret i32 %temp1 48 } 49 50 define 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 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) 62 define 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 i32 @strcmp(i8* %str1, i8* %str2) 72 ret i32 %temp3 73 } 74 75 ; strcmp(x,x) -> 0 76 define i32 @test6(i8* %str) { 77 ; CHECK-LABEL: @test6( 78 ; CHECK: ret i32 0 79 80 %temp1 = call i32 @strcmp(i8* %str, i8* %str) 81 ret i32 %temp1 82 } 83