diff options
| author | Marcin Koscielnicki <koriakin@0x04.net> | 2016-06-17 20:24:07 +0000 |
|---|---|---|
| committer | Marcin Koscielnicki <koriakin@0x04.net> | 2016-06-17 20:24:07 +0000 |
| commit | fd4b6b9e5145c0558ca0df9cee2ca28a83d398ff (patch) | |
| tree | 2bada069af453c6b41c8af1387fdd50c36bbb593 /llvm/test/CodeGen/SystemZ | |
| parent | 18d6d3d95ef4b172ae753bb11b69f0f78218e0a5 (diff) | |
| download | bcm5719-llvm-fd4b6b9e5145c0558ca0df9cee2ca28a83d398ff.tar.gz bcm5719-llvm-fd4b6b9e5145c0558ca0df9cee2ca28a83d398ff.zip | |
[SelectionDAG] Don't treat library calls specially if marked with nobuiltin.
To be used by D19781.
Differential Revision: http://reviews.llvm.org/D19801
llvm-svn: 273039
Diffstat (limited to 'llvm/test/CodeGen/SystemZ')
| -rw-r--r-- | llvm/test/CodeGen/SystemZ/memchr-nobuiltin.ll | 16 | ||||
| -rw-r--r-- | llvm/test/CodeGen/SystemZ/memcmp-nobuiltin.ll | 191 | ||||
| -rw-r--r-- | llvm/test/CodeGen/SystemZ/strcmp-nobuiltin.ll | 54 | ||||
| -rw-r--r-- | llvm/test/CodeGen/SystemZ/strcpy-nobuiltin.ll | 42 | ||||
| -rw-r--r-- | llvm/test/CodeGen/SystemZ/strlen-nobuiltin.ll | 25 |
5 files changed, 328 insertions, 0 deletions
diff --git a/llvm/test/CodeGen/SystemZ/memchr-nobuiltin.ll b/llvm/test/CodeGen/SystemZ/memchr-nobuiltin.ll new file mode 100644 index 00000000000..f94e1162ae4 --- /dev/null +++ b/llvm/test/CodeGen/SystemZ/memchr-nobuiltin.ll @@ -0,0 +1,16 @@ +; Test that memchr won't be converted to SRST if calls are +; marked with nobuiltin, eg. for sanitizers. +; +; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s + +declare i8 *@memchr(i8 *%src, i16 %char, i32 %len) + +; Test a simple forwarded call. +define i8 *@f1(i8 *%src, i16 %char, i32 %len) { +; CHECK-LABEL: f1: +; CHECK-NOT: srst +; CHECK: brasl %r14, memchr +; CHECK: br %r14 + %res = call i8 *@memchr(i8 *%src, i16 %char, i32 %len) nobuiltin + ret i8 *%res +} diff --git a/llvm/test/CodeGen/SystemZ/memcmp-nobuiltin.ll b/llvm/test/CodeGen/SystemZ/memcmp-nobuiltin.ll new file mode 100644 index 00000000000..5703552289f --- /dev/null +++ b/llvm/test/CodeGen/SystemZ/memcmp-nobuiltin.ll @@ -0,0 +1,191 @@ +; Test that memcmp won't be converted to CLC if calls are +; marked with nobuiltin, eg. for sanitizers. +; +; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s + +declare signext i32 @memcmp(i8 *%src1, i8 *%src2, i64 %size) + +; Zero-length comparisons should be optimized away. +define i32 @f1(i8 *%src1, i8 *%src2) { +; CHECK-LABEL: f1: +; CHECK-NOT: clc +; CHECK: brasl %r14, memcmp +; CHECK: br %r14 + %res = call i32 @memcmp(i8 *%src1, i8 *%src2, i64 0) nobuiltin + ret i32 %res +} + +; Check a case where the result is used as an integer. +define i32 @f2(i8 *%src1, i8 *%src2) { +; CHECK-LABEL: f2: +; CHECK-NOT: clc +; CHECK: brasl %r14, memcmp +; CHECK: br %r14 + %res = call i32 @memcmp(i8 *%src1, i8 *%src2, i64 2) nobuiltin + ret i32 %res +} + +; Check a case where the result is tested for equality. +define void @f3(i8 *%src1, i8 *%src2, i32 *%dest) { +; CHECK-LABEL: f3: +; CHECK-NOT: clc +; CHECK: brasl %r14, memcmp +; CHECK: br %r14 + %res = call i32 @memcmp(i8 *%src1, i8 *%src2, i64 3) nobuiltin + %cmp = icmp eq i32 %res, 0 + br i1 %cmp, label %exit, label %store + +store: + store i32 0, i32 *%dest + br label %exit + +exit: + ret void +} + +; Check a case where the result is tested for inequality. +define void @f4(i8 *%src1, i8 *%src2, i32 *%dest) { +; CHECK-LABEL: f4: +; CHECK-NOT: clc +; CHECK: brasl %r14, memcmp +; CHECK: br %r14 +entry: + %res = call i32 @memcmp(i8 *%src1, i8 *%src2, i64 4) nobuiltin + %cmp = icmp ne i32 %res, 0 + br i1 %cmp, label %exit, label %store + +store: + store i32 0, i32 *%dest + br label %exit + +exit: + ret void +} + +; Check a case where the result is tested via slt. +define void @f5(i8 *%src1, i8 *%src2, i32 *%dest) { +; CHECK-LABEL: f5: +; CHECK-NOT: clc +; CHECK: brasl %r14, memcmp +; CHECK: br %r14 +entry: + %res = call i32 @memcmp(i8 *%src1, i8 *%src2, i64 5) nobuiltin + %cmp = icmp slt i32 %res, 0 + br i1 %cmp, label %exit, label %store + +store: + store i32 0, i32 *%dest + br label %exit + +exit: + ret void +} + +; Check a case where the result is tested for sgt. +define void @f6(i8 *%src1, i8 *%src2, i32 *%dest) { +; CHECK-LABEL: f6: +; CHECK-NOT: clc +; CHECK: brasl %r14, memcmp +; CHECK: br %r14 +entry: + %res = call i32 @memcmp(i8 *%src1, i8 *%src2, i64 6) nobuiltin + %cmp = icmp sgt i32 %res, 0 + br i1 %cmp, label %exit, label %store + +store: + store i32 0, i32 *%dest + br label %exit + +exit: + ret void +} + +; Check the upper end of the CLC range. Here the result is used both as +; an integer and for branching. +define i32 @f7(i8 *%src1, i8 *%src2, i32 *%dest) { +; CHECK-LABEL: f7: +; CHECK-NOT: clc +; CHECK: brasl %r14, memcmp +; CHECK: br %r14 +entry: + %res = call i32 @memcmp(i8 *%src1, i8 *%src2, i64 256) nobuiltin + %cmp = icmp slt i32 %res, 0 + br i1 %cmp, label %exit, label %store + +store: + store i32 0, i32 *%dest + br label %exit + +exit: + ret i32 %res +} + +; 257 bytes needs two CLCs. +define i32 @f8(i8 *%src1, i8 *%src2) { +; CHECK-LABEL: f8: +; CHECK-NOT: clc +; CHECK: brasl %r14, memcmp +; CHECK: br %r14 + %res = call i32 @memcmp(i8 *%src1, i8 *%src2, i64 257) nobuiltin + ret i32 %res +} + +; Test a comparison of 258 bytes in which the CC result can be used directly. +define void @f9(i8 *%src1, i8 *%src2, i32 *%dest) { +; CHECK-LABEL: f9: +; CHECK-NOT: clc +; CHECK: brasl %r14, memcmp +; CHECK: br %r14 +entry: + %res = call i32 @memcmp(i8 *%src1, i8 *%src2, i64 257) nobuiltin + %cmp = icmp slt i32 %res, 0 + br i1 %cmp, label %exit, label %store + +store: + store i32 0, i32 *%dest + br label %exit + +exit: + ret void +} + +; Test the largest size that can use two CLCs. +define i32 @f10(i8 *%src1, i8 *%src2) { +; CHECK-LABEL: f10: +; CHECK-NOT: clc +; CHECK: brasl %r14, memcmp +; CHECK: br %r14 + %res = call i32 @memcmp(i8 *%src1, i8 *%src2, i64 512) nobuiltin + ret i32 %res +} + +; Test the smallest size that needs 3 CLCs. +define i32 @f11(i8 *%src1, i8 *%src2) { +; CHECK-LABEL: f11: +; CHECK-NOT: clc +; CHECK: brasl %r14, memcmp +; CHECK: br %r14 + %res = call i32 @memcmp(i8 *%src1, i8 *%src2, i64 513) nobuiltin + ret i32 %res +} + +; Test the largest size than can use 3 CLCs. +define i32 @f12(i8 *%src1, i8 *%src2) { +; CHECK-LABEL: f12: +; CHECK-NOT: clc +; CHECK: brasl %r14, memcmp +; CHECK: br %r14 + %res = call i32 @memcmp(i8 *%src1, i8 *%src2, i64 768) nobuiltin + ret i32 %res +} + +; The next size up uses a loop instead. We leave the more complicated +; loop tests to memcpy-01.ll, which shares the same form. +define i32 @f13(i8 *%src1, i8 *%src2) { +; CHECK-LABEL: f13: +; CHECK-NOT: clc +; CHECK: brasl %r14, memcmp +; CHECK: br %r14 + %res = call i32 @memcmp(i8 *%src1, i8 *%src2, i64 769) nobuiltin + ret i32 %res +} diff --git a/llvm/test/CodeGen/SystemZ/strcmp-nobuiltin.ll b/llvm/test/CodeGen/SystemZ/strcmp-nobuiltin.ll new file mode 100644 index 00000000000..187348881a6 --- /dev/null +++ b/llvm/test/CodeGen/SystemZ/strcmp-nobuiltin.ll @@ -0,0 +1,54 @@ +; Test that strcmp won't be converted to CLST if calls are +; marked with nobuiltin, eg. for sanitizers. +; +; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s + +declare signext i32 @strcmp(i8 *%src1, i8 *%src2) + +; Check a case where the result is used as an integer. +define i32 @f1(i8 *%src1, i8 *%src2) { +; CHECK-LABEL: f1: +; CHECK-NOT: clst +; CHECK: brasl %r14, strcmp +; CHECK: br %r14 + %res = call i32 @strcmp(i8 *%src1, i8 *%src2) nobuiltin + ret i32 %res +} + +; Check a case where the result is tested for equality. +define void @f2(i8 *%src1, i8 *%src2, i32 *%dest) { +; CHECK-LABEL: f2: +; CHECK-NOT: clst +; CHECK: brasl %r14, strcmp +; CHECK: br %r14 + %res = call i32 @strcmp(i8 *%src1, i8 *%src2) nobuiltin + %cmp = icmp eq i32 %res, 0 + br i1 %cmp, label %exit, label %store + +store: + store i32 0, i32 *%dest + br label %exit + +exit: + ret void +} + +; Test a case where the result is used both as an integer and for +; branching. +define i32 @f3(i8 *%src1, i8 *%src2, i32 *%dest) { +; CHECK-LABEL: f3: +; CHECK-NOT: clst +; CHECK: brasl %r14, strcmp +; CHECK: br %r14 +entry: + %res = call i32 @strcmp(i8 *%src1, i8 *%src2) nobuiltin + %cmp = icmp slt i32 %res, 0 + br i1 %cmp, label %exit, label %store + +store: + store i32 0, i32 *%dest + br label %exit + +exit: + ret i32 %res +} diff --git a/llvm/test/CodeGen/SystemZ/strcpy-nobuiltin.ll b/llvm/test/CodeGen/SystemZ/strcpy-nobuiltin.ll new file mode 100644 index 00000000000..746fd67e084 --- /dev/null +++ b/llvm/test/CodeGen/SystemZ/strcpy-nobuiltin.ll @@ -0,0 +1,42 @@ +; Test that strcmp won't be converted to MVST if calls are +; marked with nobuiltin, eg. for sanitizers. +; +; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s + +declare i8 *@strcpy(i8 *%dest, i8 *%src) +declare i8 *@stpcpy(i8 *%dest, i8 *%src) + +; Check strcpy. +define i8 *@f1(i8 *%dest, i8 *%src) { +; CHECK-LABEL: f1: +; CHECK-NOT: mvst +; CHECK: brasl %r14, strcpy +; CHECK: br %r14 + %res = call i8 *@strcpy(i8 *%dest, i8 *%src) nobuiltin + ret i8 *%res +} + +; Check stpcpy. +define i8 *@f2(i8 *%dest, i8 *%src) { +; CHECK-LABEL: f2: +; CHECK-NOT: mvst +; CHECK: brasl %r14, stpcpy +; CHECK: br %r14 + %res = call i8 *@stpcpy(i8 *%dest, i8 *%src) nobuiltin + ret i8 *%res +} + +; Check correct operation with other loads and stores. The load must +; come before the loop and the store afterwards. +define i32 @f3(i32 %dummy, i8 *%dest, i8 *%src, i32 *%resptr, i32 *%storeptr) { +; CHECK-LABEL: f3: +; CHECK-DAG: l [[REG1:%r[0-9]+]], 0(%r5) +; CHECK-NOT: mvst +; CHECK: brasl %r14, strcpy +; CHECK: mvhi 0(%r6), 0 +; CHECK: br %r14 + %res = load i32 , i32 *%resptr + %unused = call i8 *@strcpy(i8 *%dest, i8 *%src) nobuiltin + store i32 0, i32 *%storeptr + ret i32 %res +} diff --git a/llvm/test/CodeGen/SystemZ/strlen-nobuiltin.ll b/llvm/test/CodeGen/SystemZ/strlen-nobuiltin.ll new file mode 100644 index 00000000000..c16e601def3 --- /dev/null +++ b/llvm/test/CodeGen/SystemZ/strlen-nobuiltin.ll @@ -0,0 +1,25 @@ +; Test that strlen/strnlen won't be converted to SRST if calls are +; marked with nobuiltin, eg. for sanitizers. +; +; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s + +declare i64 @strlen(i8 *%src) +declare i64 @strnlen(i8 *%src, i64 %len) + +define i64 @f1(i32 %dummy, i8 *%src) { +; CHECK-LABEL: f1: +; CHECK: brasl %r14, strlen +; CHECK: br %r14 + %res = call i64 @strlen(i8 *%src) nobuiltin + ret i64 %res +} + +; Likewise for strnlen. +define i64 @f2(i64 %len, i8 *%src) { +; CHECK-LABEL: f2: +; CHECK-NOT: srst +; CHECK: brasl %r14, strnlen +; CHECK: br %r14 + %res = call i64 @strnlen(i8 *%src, i64 %len) nobuiltin + ret i64 %res +} |

