diff options
author | Petar Jovanovic <petar.jovanovic@imgtec.com> | 2016-04-13 12:25:25 +0000 |
---|---|---|
committer | Petar Jovanovic <petar.jovanovic@imgtec.com> | 2016-04-13 12:25:25 +0000 |
commit | 644b8c1a5d3773724491257fd80c24b13eb22e2c (patch) | |
tree | 99fdf93a253675b3844c32dbceb75ff33bd5a80e /llvm/test/Transforms | |
parent | 9fb77fcfef393a3a481d2fc534b76ee22531798f (diff) | |
download | bcm5719-llvm-644b8c1a5d3773724491257fd80c24b13eb22e2c.tar.gz bcm5719-llvm-644b8c1a5d3773724491257fd80c24b13eb22e2c.zip |
Calculate __builtin_object_size when pointer depends on a condition
This patch fixes calculating of builtin_object_size if it depends on a
condition. Before this patch compiler did not know how to calculate the
object size when it finds a condition that cannot be eliminated.
This patch enables calculating of builtin_object_size even in case when
condition cannot be eliminated by choosing minimum or maximum value as a
result from condition. Choosing minimum or maximum value from condition
is based on the second argument of __builtin_object_size function.
Patch by Strahinja Petrovic.
Differential Revision: http://reviews.llvm.org/D18438
llvm-svn: 266193
Diffstat (limited to 'llvm/test/Transforms')
-rw-r--r-- | llvm/test/Transforms/CodeGenPrepare/builtin-condition.ll | 90 | ||||
-rw-r--r-- | llvm/test/Transforms/InstCombine/builtin-object-size-offset.ll | 58 |
2 files changed, 148 insertions, 0 deletions
diff --git a/llvm/test/Transforms/CodeGenPrepare/builtin-condition.ll b/llvm/test/Transforms/CodeGenPrepare/builtin-condition.ll new file mode 100644 index 00000000000..e18d1b0fc0e --- /dev/null +++ b/llvm/test/Transforms/CodeGenPrepare/builtin-condition.ll @@ -0,0 +1,90 @@ +; RUN: opt -codegenprepare -S < %s | FileCheck %s + +; #include<stdlib.h> +; #define STATIC_BUF_SIZE 10 +; #define LARGER_BUF_SIZE 30 +; +; size_t foo1(int flag) { +; char *cptr; +; char chararray[LARGER_BUF_SIZE]; +; char chararray2[STATIC_BUF_SIZE]; +; if(flag) +; cptr = chararray2; +; else +; cptr = chararray; +; +; return __builtin_object_size(cptr, 2); +; } +; +; size_t foo2(int n) { +; char Small[10]; +; char Large[20]; +; char *Ptr = n ? Small : Large + 19; +; return __builtin_object_size(Ptr, 0); +; } +; +; void foo() { +; size_t ret; +; size_t ret1; +; ret = foo1(0); +; ret1 = foo2(0); +; printf("\n%d %d\n", ret, ret1); +; } + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +@.str = private unnamed_addr constant [8 x i8] c"\0A%d %d\0A\00", align 1 + +define i64 @foo1(i32 %flag) { +entry: + %chararray = alloca [30 x i8], align 16 + %chararray2 = alloca [10 x i8], align 1 + %0 = getelementptr inbounds [30 x i8], [30 x i8]* %chararray, i64 0, i64 0 + call void @llvm.lifetime.start(i64 30, i8* %0) + %1 = getelementptr inbounds [10 x i8], [10 x i8]* %chararray2, i64 0, i64 0 + call void @llvm.lifetime.start(i64 10, i8* %1) + %tobool = icmp eq i32 %flag, 0 + %cptr.0 = select i1 %tobool, i8* %0, i8* %1 + %2 = call i64 @llvm.objectsize.i64.p0i8(i8* %cptr.0, i1 true) + call void @llvm.lifetime.end(i64 10, i8* %1) + call void @llvm.lifetime.end(i64 30, i8* %0) + ret i64 %2 +; CHECK-LABEL: foo1 +; CHECK: ret i64 10 +} + +declare void @llvm.lifetime.start(i64, i8* nocapture) + +declare i64 @llvm.objectsize.i64.p0i8(i8*, i1) + +declare void @llvm.lifetime.end(i64, i8* nocapture) + +define i64 @foo2(i32 %n) { +entry: + %Small = alloca [10 x i8], align 1 + %Large = alloca [20 x i8], align 16 + %0 = getelementptr inbounds [10 x i8], [10 x i8]* %Small, i64 0, i64 0 + call void @llvm.lifetime.start(i64 10, i8* %0) + %1 = getelementptr inbounds [20 x i8], [20 x i8]* %Large, i64 0, i64 0 + call void @llvm.lifetime.start(i64 20, i8* %1) + %tobool = icmp ne i32 %n, 0 + %add.ptr = getelementptr inbounds [20 x i8], [20 x i8]* %Large, i64 0, i64 19 + %cond = select i1 %tobool, i8* %0, i8* %add.ptr + %2 = call i64 @llvm.objectsize.i64.p0i8(i8* %cond, i1 false) + call void @llvm.lifetime.end(i64 20, i8* %1) + call void @llvm.lifetime.end(i64 10, i8* %0) + ret i64 %2 +; CHECK-LABEL: foo2 +; CHECK: ret i64 10 +} + +define void @foo() { +entry: + %call = tail call i64 @foo1(i32 0) + %call1 = tail call i64 @foo2(i32 0) + %call2 = tail call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str, i64 0, i64 0), i64 %call, i64 %call1) + ret void +} + +declare i32 @printf(i8* nocapture readonly, ...)
\ No newline at end of file diff --git a/llvm/test/Transforms/InstCombine/builtin-object-size-offset.ll b/llvm/test/Transforms/InstCombine/builtin-object-size-offset.ll new file mode 100644 index 00000000000..7ab24a9acd9 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/builtin-object-size-offset.ll @@ -0,0 +1,58 @@ +; RUN: opt -instcombine -S < %s | FileCheck %s + +; #include <stdlib.h> +; #include <stdio.h> +; +; int foo1(int N) { +; char Big[20]; +; char Small[10]; +; char *Ptr = N ? Big + 10 : Small; +; return __builtin_object_size(Ptr, 0); +; } +; +; void foo() { +; size_t ret; +; ret = foo1(0); +; printf("\n %d", ret); +; } + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +@.str = private unnamed_addr constant [5 x i8] c"\0A %d\00", align 1 + +define i32 @foo1(i32 %N) { +entry: + %Big = alloca [20 x i8], align 16 + %Small = alloca [10 x i8], align 1 + %0 = getelementptr inbounds [20 x i8], [20 x i8]* %Big, i64 0, i64 0 + call void @llvm.lifetime.start(i64 20, i8* %0) + %1 = getelementptr inbounds [10 x i8], [10 x i8]* %Small, i64 0, i64 0 + call void @llvm.lifetime.start(i64 10, i8* %1) + %tobool = icmp ne i32 %N, 0 + %add.ptr = getelementptr inbounds [20 x i8], [20 x i8]* %Big, i64 0, i64 10 + %cond = select i1 %tobool, i8* %add.ptr, i8* %1 + %2 = call i64 @llvm.objectsize.i64.p0i8(i8* %cond, i1 false) + %conv = trunc i64 %2 to i32 + call void @llvm.lifetime.end(i64 10, i8* %1) + call void @llvm.lifetime.end(i64 20, i8* %0) + ret i32 %conv +; CHECK: ret i32 10 +} + +declare void @llvm.lifetime.start(i64, i8* nocapture) + +declare i64 @llvm.objectsize.i64.p0i8(i8*, i1) + +declare void @llvm.lifetime.end(i64, i8* nocapture) + +define void @foo() { +entry: + %call = tail call i32 @foo1(i32 0) + %conv = sext i32 %call to i64 + %call1 = tail call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str, i64 0, i64 0), i64 %conv) + ret void +} + +declare i32 @printf(i8* nocapture readonly, ...) + |