diff options
author | Meador Inge <meadori@codesourcery.com> | 2012-10-15 03:47:37 +0000 |
---|---|---|
committer | Meador Inge <meadori@codesourcery.com> | 2012-10-15 03:47:37 +0000 |
commit | a239c2e6a7775e890bcfb0867b84e512ceb993de (patch) | |
tree | 9d0fd3f6dc5f62bffa6b335de67fd8c5ac62b9c4 /test | |
parent | baf522ab5f365975652d2ef61831b5a426700479 (diff) | |
download | llvm-a239c2e6a7775e890bcfb0867b84e512ceb993de.tar.gz llvm-a239c2e6a7775e890bcfb0867b84e512ceb993de.tar.bz2 llvm-a239c2e6a7775e890bcfb0867b84e512ceb993de.tar.xz |
instcombine: Migrate strcmp and strncmp optimizations
This patch migrates the strcmp and strncmp optimizations from the
simplify-libcalls pass into the instcombine library call simplifier.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@165915 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test')
-rw-r--r-- | test/Transforms/InstCombine/strcmp-1.ll | 82 | ||||
-rw-r--r-- | test/Transforms/InstCombine/strcmp-2.ll | 20 | ||||
-rw-r--r-- | test/Transforms/InstCombine/strncmp-1.ll | 97 | ||||
-rw-r--r-- | test/Transforms/InstCombine/strncmp-2.ll | 20 | ||||
-rw-r--r-- | test/Transforms/InstCombine/weak-symbols.ll | 33 | ||||
-rw-r--r-- | test/Transforms/SimplifyLibCalls/StrCmp.ll | 65 | ||||
-rw-r--r-- | test/Transforms/SimplifyLibCalls/StrNCmp.ll | 78 | ||||
-rw-r--r-- | test/Transforms/SimplifyLibCalls/weak-symbols.ll | 26 |
8 files changed, 252 insertions, 169 deletions
diff --git a/test/Transforms/InstCombine/strcmp-1.ll b/test/Transforms/InstCombine/strcmp-1.ll new file mode 100644 index 0000000000..0679246e09 --- /dev/null +++ b/test/Transforms/InstCombine/strcmp-1.ll @@ -0,0 +1,82 @@ +; Test that the strcmp library call simplifier works correctly. +; RUN: opt < %s -instcombine -S | FileCheck %s + +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" + +@hello = constant [6 x i8] c"hello\00" +@hell = constant [5 x i8] c"hell\00" +@bell = constant [5 x i8] c"bell\00" +@null = constant [1 x i8] zeroinitializer + +declare i32 @strcmp(i8*, i8*) + +; strcmp("", x) -> -*x +define i32 @test1(i8* %str2) { +; CHECK: @test1 +; CHECK: %strcmpload = load i8* %str +; CHECK: %1 = zext i8 %strcmpload to i32 +; CHECK: %2 = sub i32 0, %1 +; CHECK: ret i32 %2 + + %str1 = getelementptr inbounds [1 x i8]* @null, i32 0, i32 0 + %temp1 = call i32 @strcmp(i8* %str1, i8* %str2) + ret i32 %temp1 + +} + +; strcmp(x, "") -> *x +define i32 @test2(i8* %str1) { +; CHECK: @test2 +; CHECK: %strcmpload = load i8* %str +; CHECK: %1 = zext i8 %strcmpload to i32 +; CHECK: ret i32 %1 + + %str2 = getelementptr inbounds [1 x i8]* @null, i32 0, i32 0 + %temp1 = call i32 @strcmp(i8* %str1, i8* %str2) + ret i32 %temp1 +} + +; strcmp(x, y) -> cnst +define i32 @test3() { +; CHECK: @test3 +; CHECK: ret i32 -1 + + %str1 = getelementptr inbounds [5 x i8]* @hell, i32 0, i32 0 + %str2 = getelementptr inbounds [6 x i8]* @hello, i32 0, i32 0 + %temp1 = call i32 @strcmp(i8* %str1, i8* %str2) + ret i32 %temp1 +} + +define i32 @test4() { +; CHECK: @test4 +; CHECK: ret i32 1 + + %str1 = getelementptr inbounds [5 x i8]* @hell, i32 0, i32 0 + %str2 = getelementptr inbounds [1 x i8]* @null, i32 0, i32 0 + %temp1 = call i32 @strcmp(i8* %str1, i8* %str2) + ret i32 %temp1 +} + +; strcmp(x, y) -> memcmp(x, y, <known length>) +; (This transform is rather difficult to trigger in a useful manner) +define i32 @test5(i1 %b) { +; CHECK: @test5 +; CHECK: %memcmp = call i32 @memcmp(i8* getelementptr inbounds ([6 x i8]* @hello, i32 0, i32 0), i8* %str2, i32 5) +; CHECK: ret i32 %memcmp + + %str1 = getelementptr inbounds [6 x i8]* @hello, i32 0, i32 0 + %temp1 = getelementptr inbounds [5 x i8]* @hell, i32 0, i32 0 + %temp2 = getelementptr inbounds [5 x i8]* @bell, i32 0, i32 0 + %str2 = select i1 %b, i8* %temp1, i8* %temp2 + %temp3 = call i32 @strcmp(i8* %str1, i8* %str2) + ret i32 %temp3 +} + +; strcmp(x,x) -> 0 +define i32 @test6(i8* %str) { +; CHECK: @test6 +; CHECK: ret i32 0 + + %temp1 = call i32 @strcmp(i8* %str, i8* %str) + ret i32 %temp1 +} diff --git a/test/Transforms/InstCombine/strcmp-2.ll b/test/Transforms/InstCombine/strcmp-2.ll new file mode 100644 index 0000000000..20518960f3 --- /dev/null +++ b/test/Transforms/InstCombine/strcmp-2.ll @@ -0,0 +1,20 @@ +; Test that the strcmp library call simplifier works correctly. +; RUN: opt < %s -instcombine -S | FileCheck %s + +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" + +@hello = constant [6 x i8] c"hello\00" +@hell = constant [5 x i8] c"hell\00" + +declare i16 @strcmp(i8*, i8*) + +define i16 @test_nosimplify() { +; CHECK: @test_nosimplify +; CHECK: call i16 @strcmp +; CHECK: ret i16 %temp1 + + %str1 = getelementptr inbounds [5 x i8]* @hell, i32 0, i32 0 + %str2 = getelementptr inbounds [6 x i8]* @hello, i32 0, i32 0 + %temp1 = call i16 @strcmp(i8* %str1, i8* %str2) + ret i16 %temp1 +} diff --git a/test/Transforms/InstCombine/strncmp-1.ll b/test/Transforms/InstCombine/strncmp-1.ll new file mode 100644 index 0000000000..48b26d1a5f --- /dev/null +++ b/test/Transforms/InstCombine/strncmp-1.ll @@ -0,0 +1,97 @@ +; Test that the strncmp library call simplifier works correctly. +; RUN: opt < %s -instcombine -S | FileCheck %s + +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" + +@hello = constant [6 x i8] c"hello\00" +@hell = constant [5 x i8] c"hell\00" +@bell = constant [5 x i8] c"bell\00" +@null = constant [1 x i8] zeroinitializer + +declare i32 @strncmp(i8*, i8*, i32) + +; strncmp("", x, n) -> -*x +define i32 @test1(i8* %str2) { +; CHECK: @test1 +; CHECK: %strcmpload = load i8* %str +; CHECK: %1 = zext i8 %strcmpload to i32 +; CHECK: %2 = sub i32 0, %1 +; CHECK: ret i32 %2 + + %str1 = getelementptr inbounds [1 x i8]* @null, i32 0, i32 0 + %temp1 = call i32 @strncmp(i8* %str1, i8* %str2, i32 10) + ret i32 %temp1 +} + +; strncmp(x, "", n) -> *x +define i32 @test2(i8* %str1) { +; CHECK: @test2 +; CHECK: %strcmpload = load i8* %str1 +; CHECK: %1 = zext i8 %strcmpload to i32 +; CHECK: ret i32 %1 + + %str2 = getelementptr inbounds [1 x i8]* @null, i32 0, i32 0 + %temp1 = call i32 @strncmp(i8* %str1, i8* %str2, i32 10) + ret i32 %temp1 +} + +; strncmp(x, y, n) -> cnst +define i32 @test3() { +; CHECK: @test3 +; CHECK: ret i32 -1 + + %str1 = getelementptr inbounds [5 x i8]* @hell, i32 0, i32 0 + %str2 = getelementptr inbounds [6 x i8]* @hello, i32 0, i32 0 + %temp1 = call i32 @strncmp(i8* %str1, i8* %str2, i32 10) + ret i32 %temp1 +} + +define i32 @test4() { +; CHECK: @test4 +; CHECK: ret i32 1 + + %str1 = getelementptr inbounds [5 x i8]* @hell, i32 0, i32 0 + %str2 = getelementptr inbounds [1 x i8]* @null, i32 0, i32 0 + %temp1 = call i32 @strncmp(i8* %str1, i8* %str2, i32 10) + ret i32 %temp1 +} + +define i32 @test5() { +; CHECK: @test5 +; CHECK: ret i32 0 + + %str1 = getelementptr inbounds [5 x i8]* @hell, i32 0, i32 0 + %str2 = getelementptr inbounds [6 x i8]* @hello, i32 0, i32 0 + %temp1 = call i32 @strncmp(i8* %str1, i8* %str2, i32 4) + ret i32 %temp1 +} + +; strncmp(x,y,1) -> memcmp(x,y,1) +; TODO: Once the memcmp simplifier gets moved into the instcombine pass +; the following memcmp will be folded into two loads and a subtract. +define i32 @test6(i8* %str1, i8* %str2) { +; CHECK: @test6 +; CHECK: call i32 @memcmp +; CHECK: ret i32 %memcmp + + %temp1 = call i32 @strncmp(i8* %str1, i8* %str2, i32 1) + ret i32 %temp1 +} + +; strncmp(x,y,0) -> 0 +define i32 @test7(i8* %str1, i8* %str2) { +; CHECK: @test7 +; CHECK: ret i32 0 + + %temp1 = call i32 @strncmp(i8* %str1, i8* %str2, i32 0) + ret i32 %temp1 +} + +; strncmp(x,x,n) -> 0 +define i32 @test8(i8* %str, i32 %n) { +; CHECK: @test8 +; CHECK: ret i32 0 + + %temp1 = call i32 @strncmp(i8* %str, i8* %str, i32 %n) + ret i32 %temp1 +} diff --git a/test/Transforms/InstCombine/strncmp-2.ll b/test/Transforms/InstCombine/strncmp-2.ll new file mode 100644 index 0000000000..3fc43a6fd4 --- /dev/null +++ b/test/Transforms/InstCombine/strncmp-2.ll @@ -0,0 +1,20 @@ +; Test that the strncmp library call simplifier works correctly. +; RUN: opt < %s -instcombine -S | FileCheck %s + +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" + +@hello = constant [6 x i8] c"hello\00" +@hell = constant [5 x i8] c"hell\00" + +declare i16 @strncmp(i8*, i8*, i32) + +define i16 @test_nosimplify() { +; CHECK: @test_nosimplify +; CHECK: call i16 @strncmp +; CHECK: ret i16 %temp1 + + %str1 = getelementptr inbounds [5 x i8]* @hell, i32 0, i32 0 + %str2 = getelementptr inbounds [6 x i8]* @hello, i32 0, i32 0 + %temp1 = call i16 @strncmp(i8* %str1, i8* %str2, i32 10) + ret i16 %temp1 +} diff --git a/test/Transforms/InstCombine/weak-symbols.ll b/test/Transforms/InstCombine/weak-symbols.ll new file mode 100644 index 0000000000..0039b5962f --- /dev/null +++ b/test/Transforms/InstCombine/weak-symbols.ll @@ -0,0 +1,33 @@ +; PR4738 - Test that the library call simplifier doesn't assume anything about +; weak symbols. +; +; RUN: opt < %s -instcombine -S | FileCheck %s + +@real_init = weak_odr constant [2 x i8] c"y\00" +@fake_init = weak constant [2 x i8] c"y\00" +@.str = private constant [2 x i8] c"y\00" + +define i32 @foo() nounwind { +; CHECK: define i32 @foo +; CHECK: call i32 @strcmp +; CHECK: ret i32 %temp1 + +entry: + %str1 = getelementptr inbounds [2 x i8]* @fake_init, i64 0, i64 0 + %str2 = getelementptr inbounds [2 x i8]* @.str, i64 0, i64 0 + %temp1 = call i32 @strcmp(i8* %str1, i8* %str2) nounwind readonly + ret i32 %temp1 +} + +define i32 @bar() nounwind { +; CHECK: define i32 @bar +; CHECK: ret i32 0 + +entry: + %str1 = getelementptr inbounds [2 x i8]* @real_init, i64 0, i64 0 + %str2 = getelementptr inbounds [2 x i8]* @.str, i64 0, i64 0 + %temp1 = call i32 @strcmp(i8* %str1, i8* %str2) nounwind readonly + ret i32 %temp1 +} + +declare i32 @strcmp(i8*, i8*) nounwind readonly diff --git a/test/Transforms/SimplifyLibCalls/StrCmp.ll b/test/Transforms/SimplifyLibCalls/StrCmp.ll deleted file mode 100644 index 60854d76c9..0000000000 --- a/test/Transforms/SimplifyLibCalls/StrCmp.ll +++ /dev/null @@ -1,65 +0,0 @@ -; Test that the StrCmpOptimizer works correctly -; RUN: opt < %s -simplify-libcalls -S | FileCheck %s - -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" - -@hello = constant [6 x i8] c"hello\00" ; <[6 x i8]*> [#uses=1] -@hell = constant [5 x i8] c"hell\00" ; <[5 x i8]*> [#uses=1] -@bell = constant [5 x i8] c"bell\00" ; <[5 x i8]*> [#uses=1] -@null = constant [1 x i8] zeroinitializer ; <[1 x i8]*> [#uses=1] - -declare i32 @strcmp(i8*, i8*) - -; strcmp("", x) -> -*x -define i32 @test1(i8* %str) { - %temp1 = call i32 @strcmp(i8* getelementptr inbounds ([1 x i8]* @null, i32 0, i32 0), i8* %str) - ret i32 %temp1 - ; CHECK: @test1 - ; CHECK: %strcmpload = load i8* %str - ; CHECK: %1 = zext i8 %strcmpload to i32 - ; CHECK: %temp1 = sub i32 0, %1 - ; CHECK: ret i32 %temp1 -} - -; strcmp(x, "") -> *x -define i32 @test2(i8* %str) { - %temp1 = call i32 @strcmp(i8* %str, i8* getelementptr inbounds ([1 x i8]* @null, i32 0, i32 0)) - ret i32 %temp1 - ; CHECK: @test2 - ; CHECK: %strcmpload = load i8* %str - ; CHECK: %temp1 = zext i8 %strcmpload to i32 - ; CHECK: ret i32 %temp1 -} - -; strcmp(x, y) -> cnst -define i32 @test3() { - %temp1 = call i32 @strcmp(i8* getelementptr inbounds ([5 x i8]* @hell, i32 0, i32 0), i8* getelementptr inbounds ([6 x i8]* @hello, i32 0, i32 0)) - ret i32 %temp1 - ; CHECK: @test3 - ; CHECK: ret i32 -1 -} -define i32 @test4() { - %temp1 = call i32 @strcmp(i8* getelementptr inbounds ([5 x i8]* @hell, i32 0, i32 0), i8* getelementptr inbounds ([1 x i8]* @null, i32 0, i32 0)) - ret i32 %temp1 - ; CHECK: @test4 - ; CHECK: ret i32 1 -} - -; strcmp(x, y) -> memcmp(x, y, <known length>) -; (This transform is rather difficult to trigger in a useful manner) -define i32 @test5(i1 %b) { - %sel = select i1 %b, i8* getelementptr inbounds ([5 x i8]* @hell, i32 0, i32 0), i8* getelementptr inbounds ([5 x i8]* @bell, i32 0, i32 0) - %temp1 = call i32 @strcmp(i8* getelementptr inbounds ([6 x i8]* @hello, i32 0, i32 0), i8* %sel) - ret i32 %temp1 - ; CHECK: @test5 - ; CHECK: %memcmp = call i32 @memcmp(i8* getelementptr inbounds ([6 x i8]* @hello, i32 0, i32 0), i8* %sel, i32 5) - ; CHECK: ret i32 %memcmp -} - -; strcmp(x,x) -> 0 -define i32 @test6(i8* %str) { - %temp1 = call i32 @strcmp(i8* %str, i8* %str) - ret i32 %temp1 - ; CHECK: @test6 - ; CHECK: ret i32 0 -} diff --git a/test/Transforms/SimplifyLibCalls/StrNCmp.ll b/test/Transforms/SimplifyLibCalls/StrNCmp.ll deleted file mode 100644 index 0b2a501a3c..0000000000 --- a/test/Transforms/SimplifyLibCalls/StrNCmp.ll +++ /dev/null @@ -1,78 +0,0 @@ -; Test that the StrCmpOptimizer works correctly -; RUN: opt < %s -simplify-libcalls -S | FileCheck %s - -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" - -@hello = constant [6 x i8] c"hello\00" ; <[6 x i8]*> [#uses=1] -@hell = constant [5 x i8] c"hell\00" ; <[5 x i8]*> [#uses=1] -@bell = constant [5 x i8] c"bell\00" ; <[5 x i8]*> [#uses=1] -@null = constant [1 x i8] zeroinitializer ; <[1 x i8]*> [#uses=1] - -declare i32 @strncmp(i8*, i8*, i32) - -; strcmp("", x) -> -*x -define i32 @test1(i8* %str) { - %temp1 = call i32 @strncmp(i8* getelementptr inbounds ([1 x i8]* @null, i32 0, i32 0), i8* %str, i32 10) - ret i32 %temp1 - ; CHECK: @test1 - ; CHECK: %strcmpload = load i8* %str - ; CHECK: %1 = zext i8 %strcmpload to i32 - ; CHECK: %temp1 = sub i32 0, %1 - ; CHECK: ret i32 %temp1 -} - -; strcmp(x, "") -> *x -define i32 @test2(i8* %str) { - %temp1 = call i32 @strncmp(i8* %str, i8* getelementptr inbounds ([1 x i8]* @null, i32 0, i32 0), i32 10) - ret i32 %temp1 - ; CHECK: @test2 - ; CHECK: %strcmpload = load i8* %str - ; CHECK: %temp1 = zext i8 %strcmpload to i32 - ; CHECK: ret i32 %temp1 -} - -; strncmp(x, y, n) -> cnst -define i32 @test3() { - %temp1 = call i32 @strncmp(i8* getelementptr inbounds ([5 x i8]* @hell, i32 0, i32 0), i8* getelementptr inbounds ([6 x i8]* @hello, i32 0, i32 0), i32 10) - ret i32 %temp1 - ; CHECK: @test3 - ; CHECK: ret i32 -1 -} -define i32 @test4() { - %temp1 = call i32 @strncmp(i8* getelementptr inbounds ([5 x i8]* @hell, i32 0, i32 0), i8* getelementptr inbounds ([1 x i8]* @null, i32 0, i32 0), i32 10) - ret i32 %temp1 - ; CHECK: @test4 - ; CHECK: ret i32 1 -} -define i32 @test5() { - %temp1 = call i32 @strncmp(i8* getelementptr inbounds ([5 x i8]* @hell, i32 0, i32 0), i8* getelementptr inbounds ([6 x i8]* @hello, i32 0, i32 0), i32 4) - ret i32 %temp1 - ; CHECK: @test5 - ; CHECK: ret i32 0 -} - -; strncmp(x,y,1) -> memcmp(x,y,1) -define i32 @test6(i8* %str1, i8* %str2) { - %temp1 = call i32 @strncmp(i8* %str1, i8* %str2, i32 1) - ret i32 %temp1 - ; CHECK: @test6 - ; CHECK: load i8* - ; CHECK: load i8* - ; CHECK: sub i32 -} - -; strncmp(x,y,0) -> 0 -define i32 @test7(i8* %str1, i8* %str2) { - %temp1 = call i32 @strncmp(i8* %str1, i8* %str2, i32 0) - ret i32 %temp1 - ; CHECK: @test7 - ; CHECK: ret i32 0 -} - -; strncmp(x,x,n) -> 0 -define i32 @test8(i8* %str, i32 %n) { - %temp1 = call i32 @strncmp(i8* %str, i8* %str, i32 %n) - ret i32 %temp1 - ; CHECK: @test8 - ; CHECK: ret i32 0 -} diff --git a/test/Transforms/SimplifyLibCalls/weak-symbols.ll b/test/Transforms/SimplifyLibCalls/weak-symbols.ll deleted file mode 100644 index 5875b211f7..0000000000 --- a/test/Transforms/SimplifyLibCalls/weak-symbols.ll +++ /dev/null @@ -1,26 +0,0 @@ -; RUN: opt < %s -simplify-libcalls -S | FileCheck %s -; PR4738 - -; SimplifyLibcalls shouldn't assume anything about weak symbols. - -@real_init = weak_odr constant [2 x i8] c"y\00" -@fake_init = weak constant [2 x i8] c"y\00" -@.str = private constant [2 x i8] c"y\00" - -; CHECK: define i32 @foo -; CHECK: call i32 @strcmp -define i32 @foo() nounwind { -entry: - %t0 = call i32 @strcmp(i8* getelementptr inbounds ([2 x i8]* @fake_init, i64 0, i64 0), i8* getelementptr inbounds ([2 x i8]* @.str, i64 0, i64 0)) nounwind readonly - ret i32 %t0 -} - -; CHECK: define i32 @bar -; CHECK: ret i32 0 -define i32 @bar() nounwind { -entry: - %t0 = call i32 @strcmp(i8* getelementptr inbounds ([2 x i8]* @real_init, i64 0, i64 0), i8* getelementptr inbounds ([2 x i8]* @.str, i64 0, i64 0)) nounwind readonly - ret i32 %t0 -} - -declare i32 @strcmp(i8*, i8*) nounwind readonly |