2013-08-14 00:24:38 +00:00
|
|
|
; RUN: opt < %s -instcombine -S -default-data-layout="E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" | FileCheck %s
|
|
|
|
; RUN: opt < %s -instcombine -S -default-data-layout="E-p:32:32:32-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" | FileCheck %s -check-prefix=P32
|
|
|
|
; RUN: opt < %s -instcombine -S | FileCheck %s -check-prefix=NODL
|
2004-03-19 06:07:43 +00:00
|
|
|
|
|
|
|
|
2008-03-09 08:16:40 +00:00
|
|
|
declare void @use(...)
|
|
|
|
|
Replacing zero-sized alloca's with a null pointer is too aggressive, instead
merge all zero-sized alloca's into one, fixing c43204g from the Ada ACATS
conformance testsuite. What happened there was that a variable sized object
was being allocated on the stack, "alloca i8, i32 %size". It was then being
passed to another function, which tested that the address was not null (raising
an exception if it was) then manipulated %size bytes in it (load and/or store).
The optimizers cleverly managed to deduce that %size was zero (congratulations
to them, as it isn't at all obvious), which made the alloca zero size, causing
the optimizers to replace it with null, which then caused the check mentioned
above to fail, and the exception to be raised, wrongly. Note that no loads
and stores were actually being done to the alloca (the loop that does them is
executed %size times, i.e. is not executed), only the not-null address check.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@159202 91177308-0d34-0410-b5e6-96231b3b80d8
2012-06-26 13:39:21 +00:00
|
|
|
@int = global i32 zeroinitializer
|
|
|
|
|
|
|
|
; Zero byte allocas should be merged if they can't be deleted.
|
2013-07-14 01:42:54 +00:00
|
|
|
; CHECK-LABEL: @test(
|
Replacing zero-sized alloca's with a null pointer is too aggressive, instead
merge all zero-sized alloca's into one, fixing c43204g from the Ada ACATS
conformance testsuite. What happened there was that a variable sized object
was being allocated on the stack, "alloca i8, i32 %size". It was then being
passed to another function, which tested that the address was not null (raising
an exception if it was) then manipulated %size bytes in it (load and/or store).
The optimizers cleverly managed to deduce that %size was zero (congratulations
to them, as it isn't at all obvious), which made the alloca zero size, causing
the optimizers to replace it with null, which then caused the check mentioned
above to fail, and the exception to be raised, wrongly. Note that no loads
and stores were actually being done to the alloca (the loop that does them is
executed %size times, i.e. is not executed), only the not-null address check.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@159202 91177308-0d34-0410-b5e6-96231b3b80d8
2012-06-26 13:39:21 +00:00
|
|
|
; CHECK: alloca
|
2010-05-28 15:09:00 +00:00
|
|
|
; CHECK-NOT: alloca
|
2008-03-09 08:16:40 +00:00
|
|
|
define void @test() {
|
|
|
|
%X = alloca [0 x i32] ; <[0 x i32]*> [#uses=1]
|
|
|
|
call void (...)* @use( [0 x i32]* %X )
|
|
|
|
%Y = alloca i32, i32 0 ; <i32*> [#uses=1]
|
|
|
|
call void (...)* @use( i32* %Y )
|
|
|
|
%Z = alloca { } ; <{ }*> [#uses=1]
|
|
|
|
call void (...)* @use( { }* %Z )
|
Replacing zero-sized alloca's with a null pointer is too aggressive, instead
merge all zero-sized alloca's into one, fixing c43204g from the Ada ACATS
conformance testsuite. What happened there was that a variable sized object
was being allocated on the stack, "alloca i8, i32 %size". It was then being
passed to another function, which tested that the address was not null (raising
an exception if it was) then manipulated %size bytes in it (load and/or store).
The optimizers cleverly managed to deduce that %size was zero (congratulations
to them, as it isn't at all obvious), which made the alloca zero size, causing
the optimizers to replace it with null, which then caused the check mentioned
above to fail, and the exception to be raised, wrongly. Note that no loads
and stores were actually being done to the alloca (the loop that does them is
executed %size times, i.e. is not executed), only the not-null address check.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@159202 91177308-0d34-0410-b5e6-96231b3b80d8
2012-06-26 13:39:21 +00:00
|
|
|
%size = load i32* @int
|
|
|
|
%A = alloca {{}}, i32 %size
|
|
|
|
call void (...)* @use( {{}}* %A )
|
2008-03-09 08:16:40 +00:00
|
|
|
ret void
|
2004-03-19 06:07:43 +00:00
|
|
|
}
|
2007-01-15 06:51:25 +00:00
|
|
|
|
2010-05-28 15:09:00 +00:00
|
|
|
; Zero byte allocas should be deleted.
|
2013-07-14 01:42:54 +00:00
|
|
|
; CHECK-LABEL: @test2(
|
2010-05-28 15:09:00 +00:00
|
|
|
; CHECK-NOT: alloca
|
2008-03-09 08:16:40 +00:00
|
|
|
define void @test2() {
|
|
|
|
%A = alloca i32 ; <i32*> [#uses=1]
|
|
|
|
store i32 123, i32* %A
|
|
|
|
ret void
|
2007-01-15 06:51:25 +00:00
|
|
|
}
|
|
|
|
|
2010-05-28 15:09:00 +00:00
|
|
|
; Zero byte allocas should be deleted.
|
2013-07-14 01:42:54 +00:00
|
|
|
; CHECK-LABEL: @test3(
|
2010-05-28 15:09:00 +00:00
|
|
|
; CHECK-NOT: alloca
|
2008-03-09 08:16:40 +00:00
|
|
|
define void @test3() {
|
|
|
|
%A = alloca { i32 } ; <{ i32 }*> [#uses=1]
|
|
|
|
%B = getelementptr { i32 }* %A, i32 0, i32 0 ; <i32*> [#uses=1]
|
|
|
|
store i32 123, i32* %B
|
|
|
|
ret void
|
2007-01-15 06:51:25 +00:00
|
|
|
}
|
2008-03-09 08:16:40 +00:00
|
|
|
|
2013-07-14 01:42:54 +00:00
|
|
|
; CHECK-LABEL: @test4(
|
2010-05-28 15:09:00 +00:00
|
|
|
; CHECK: = zext i32 %n to i64
|
|
|
|
; CHECK: %A = alloca i32, i64 %
|
|
|
|
define i32* @test4(i32 %n) {
|
|
|
|
%A = alloca i32, i32 %n
|
|
|
|
ret i32* %A
|
|
|
|
}
|
2012-04-08 14:36:56 +00:00
|
|
|
|
|
|
|
; Allocas which are only used by GEPs, bitcasts, and stores (transitively)
|
|
|
|
; should be deleted.
|
|
|
|
define void @test5() {
|
2013-07-14 01:42:54 +00:00
|
|
|
; CHECK-LABEL: @test5(
|
2012-04-08 14:36:56 +00:00
|
|
|
; CHECK-NOT: alloca
|
|
|
|
; CHECK-NOT: store
|
|
|
|
; CHECK: ret
|
|
|
|
|
|
|
|
entry:
|
|
|
|
%a = alloca { i32 }
|
|
|
|
%b = alloca i32*
|
|
|
|
%a.1 = getelementptr { i32 }* %a, i32 0, i32 0
|
|
|
|
store i32 123, i32* %a.1
|
|
|
|
store i32* %a.1, i32** %b
|
|
|
|
%b.1 = bitcast i32** %b to i32*
|
|
|
|
store i32 123, i32* %b.1
|
|
|
|
%a.2 = getelementptr { i32 }* %a, i32 0, i32 0
|
|
|
|
store atomic i32 2, i32* %a.2 unordered, align 4
|
|
|
|
%a.3 = getelementptr { i32 }* %a, i32 0, i32 0
|
|
|
|
store atomic i32 3, i32* %a.3 release, align 4
|
|
|
|
%a.4 = getelementptr { i32 }* %a, i32 0, i32 0
|
|
|
|
store atomic i32 4, i32* %a.4 seq_cst, align 4
|
|
|
|
ret void
|
|
|
|
}
|
|
|
|
|
|
|
|
declare void @f(i32* %p)
|
|
|
|
|
|
|
|
; Check that we don't delete allocas in some erroneous cases.
|
|
|
|
define void @test6() {
|
2013-07-14 01:42:54 +00:00
|
|
|
; CHECK-LABEL: @test6(
|
2012-04-08 14:36:56 +00:00
|
|
|
; CHECK-NOT: ret
|
|
|
|
; CHECK: alloca
|
|
|
|
; CHECK-NEXT: alloca
|
|
|
|
; CHECK: ret
|
|
|
|
|
|
|
|
entry:
|
|
|
|
%a = alloca { i32 }
|
|
|
|
%b = alloca i32
|
|
|
|
%a.1 = getelementptr { i32 }* %a, i32 0, i32 0
|
|
|
|
store volatile i32 123, i32* %a.1
|
|
|
|
tail call void @f(i32* %b)
|
|
|
|
ret void
|
|
|
|
}
|
2012-11-18 05:39:39 +00:00
|
|
|
|
|
|
|
; PR14371
|
|
|
|
%opaque_type = type opaque
|
|
|
|
%real_type = type { { i32, i32* } }
|
|
|
|
|
|
|
|
@opaque_global = external constant %opaque_type, align 4
|
|
|
|
|
|
|
|
define void @test7() {
|
|
|
|
entry:
|
|
|
|
%0 = alloca %real_type, align 4
|
|
|
|
%1 = bitcast %real_type* %0 to i8*
|
|
|
|
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %1, i8* bitcast (%opaque_type* @opaque_global to i8*), i32 8, i32 1, i1 false)
|
|
|
|
ret void
|
|
|
|
}
|
|
|
|
|
|
|
|
declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind
|
2013-08-14 00:24:38 +00:00
|
|
|
|
|
|
|
|
|
|
|
; Check that the GEP indices use the pointer size, or 64 if unknown
|
|
|
|
define void @test8() {
|
|
|
|
; CHECK-LABEL: @test8(
|
|
|
|
; CHECK: alloca [100 x i32]
|
|
|
|
; CHECK: getelementptr inbounds [100 x i32]* %x1, i64 0, i64 0
|
|
|
|
|
|
|
|
; P32-LABEL: @test8(
|
|
|
|
; P32: alloca [100 x i32]
|
|
|
|
; P32: getelementptr inbounds [100 x i32]* %x1, i32 0, i32 0
|
|
|
|
|
|
|
|
; NODL-LABEL: @test8(
|
|
|
|
; NODL: alloca [100 x i32]
|
|
|
|
; NODL: getelementptr inbounds [100 x i32]* %x1, i64 0, i64 0
|
|
|
|
%x = alloca i32, i32 100
|
|
|
|
call void (...)* @use(i32* %x)
|
|
|
|
ret void
|
|
|
|
}
|
2014-04-28 17:40:03 +00:00
|
|
|
|
|
|
|
; PR19569
|
|
|
|
%struct_type = type { i32, i32 }
|
|
|
|
declare void @test9_aux(<{ %struct_type }>* inalloca)
|
|
|
|
declare i8* @llvm.stacksave()
|
|
|
|
declare void @llvm.stackrestore(i8*)
|
|
|
|
|
|
|
|
define void @test9(%struct_type* %a) {
|
|
|
|
; CHECK-LABEL: @test9(
|
|
|
|
entry:
|
|
|
|
%inalloca.save = call i8* @llvm.stacksave()
|
|
|
|
%argmem = alloca inalloca <{ %struct_type }>
|
|
|
|
; CHECK: alloca inalloca i64, align 8
|
|
|
|
%0 = getelementptr inbounds <{ %struct_type }>* %argmem, i32 0, i32 0
|
|
|
|
%1 = bitcast %struct_type* %0 to i8*
|
|
|
|
%2 = bitcast %struct_type* %a to i8*
|
|
|
|
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %1, i8* %2, i32 8, i32 4, i1 false)
|
|
|
|
call void @test9_aux(<{ %struct_type }>* inalloca %argmem)
|
|
|
|
call void @llvm.stackrestore(i8* %inalloca.save)
|
|
|
|
ret void
|
|
|
|
}
|