blob: fab28064c9c32ed81ffed9cf0f4cb92395bc8a80 [file] [edit]
; RUN: opt < %s -simplify-allocas -S | FileCheck %s
target datalayout = "p:32:32:32"
%struct = type { i32, i32 }
declare void @receive_alloca(%struct* %ptr)
declare void @receive_vector_alloca(<4 x i32>* %ptr)
define void @alloca_fixed() {
%buf = alloca %struct, align 128
call void @receive_alloca(%struct* %buf)
ret void
}
; CHECK-LABEL: define void @alloca_fixed() {
; CHECK-NEXT: %buf = alloca i8, i32 8, align 128
; CHECK-NEXT: %buf.bc = bitcast i8* %buf to %struct*
; CHECK-NEXT: call void @receive_alloca(%struct* %buf.bc)
; When the size passed to alloca is a constant, it should be a
; constant in the output too.
define void @alloca_fixed_array() {
%buf = alloca %struct, i32 100
call void @receive_alloca(%struct* %buf)
ret void
}
; CHECK-LABEL: define void @alloca_fixed_array() {
; CHECK-NEXT: %buf = alloca i8, i32 800, align 8
; CHECK-NEXT: %buf.bc = bitcast i8* %buf to %struct*
; CHECK-NEXT: call void @receive_alloca(%struct* %buf.bc)
define void @alloca_fixed_vector() {
%buf = alloca <4 x i32>, align 128
call void @receive_vector_alloca(<4 x i32>* %buf)
ret void
}
; CHECK-LABEL: define void @alloca_fixed_vector() {
; CHECK-NEXT: %buf = alloca i8, i32 16, align 128
; CHECK-NEXT: %buf.bc = bitcast i8* %buf to <4 x i32>*
; CHECK-NEXT: call void @receive_vector_alloca(<4 x i32>* %buf.bc)
define void @alloca_variable(i32 %size) {
%buf = alloca %struct, i32 %size
call void @receive_alloca(%struct* %buf)
ret void
}
; CHECK-LABEL: define void @alloca_variable(i32 %size) {
; CHECK-NEXT: %buf.alloca_mul = mul i32 8, %size
; CHECK-NEXT: %buf = alloca i8, i32 %buf.alloca_mul
; CHECK-NEXT: %buf.bc = bitcast i8* %buf to %struct*
; CHECK-NEXT: call void @receive_alloca(%struct* %buf.bc)
define void @alloca_alignment_i32() {
%buf = alloca i32
ret void
}
; CHECK-LABEL: void @alloca_alignment_i32() {
; CHECK-NEXT: alloca i8, i32 4, align 4
define void @alloca_alignment_double() {
%buf = alloca double
ret void
}
; CHECK-LABEL: void @alloca_alignment_double() {
; CHECK-NEXT: alloca i8, i32 8, align 8
define void @alloca_lower_alignment() {
%buf = alloca i32, align 1
ret void
}
; CHECK-LABEL: void @alloca_lower_alignment() {
; CHECK-NEXT: alloca i8, i32 4, align 1
define void @alloca_array_trunc() {
%a = alloca i32, i64 1024
unreachable
}
; CHECK-LABEL: define void @alloca_array_trunc()
; CHECK-NEXT: %a = alloca i8, i32 4096
define void @alloca_array_zext() {
%a = alloca i32, i8 128
unreachable
}
; CHECK-LABEL: define void @alloca_array_zext()
; CHECK-NEXT: %a = alloca i8, i32 512
define void @dyn_alloca_array_trunc(i64 %a) {
%b = alloca i32, i64 %a
unreachable
}
; CHECK-LABEL: define void @dyn_alloca_array_trunc(i64 %a)
; CHECK-NEXT: trunc i64 %a to i32
; CHECK-NEXT: mul i32 4,
; CHECK-NEXT: alloca i8, i32
define void @dyn_alloca_array_zext(i8 %a) {
%b = alloca i32, i8 %a
unreachable
}
; CHECK-LABEL: define void @dyn_alloca_array_zext(i8 %a)
; CHECK-NEXT: zext i8 %a to i32
; CHECK-NEXT: mul i32 4,
; CHECK-NEXT: alloca i8, i32
define void @dyn_inst_alloca_array(i32 %a) {
%b = add i32 1, %a
%c = alloca i32, i32 %b
unreachable
}
; CHECK-LABEL: define void @dyn_inst_alloca_array(i32 %a)
; CHECK-NEXT: %b = add i32 1, %a
; CHECK-NEXT: mul i32 4, %b
; CHECK-NEXT: %c = alloca i8, i32
define void @dyn_inst_alloca_array_trunc(i64 %a) {
%b = add i64 1, %a
%c = alloca i32, i64 %b
unreachable
}
; CHECK-LABEL: define void @dyn_inst_alloca_array_trunc(i64 %a)
; CHECK-NEXT: %b = add i64 1, %a
; CHECK-NEXT: trunc i64 %b to i32
; CHECK-NEXT: mul i32 4,
; CHECK-NEXT: %c = alloca i8, i32
define void @dyn_inst_alloca_array_zext(i8 %a) {
%b = add i8 1, %a
%c = alloca i32, i8 %b
unreachable
}
; CHECK-LABEL: define void @dyn_inst_alloca_array_zext(i8 %a)
; CHECK-NEXT: %b = add i8 1, %a
; CHECK-NEXT: zext i8 %b to i32
; CHECK-NEXT: mul i32 4,
; CHECK-NEXT: %c = alloca i8, i32
declare void @llvm.dbg.declare(metadata, metadata, metadata)
define void @debug_declare() {
%var = alloca i32
call void @llvm.dbg.declare(metadata i32* %var, metadata !12, metadata !13), !dbg !14
unreachable
}
; Ensure that the first arg to dbg.declare points to the alloca, not the bitcast
; CHECK-LABEL: define void @debug_declare
; CHECK-NEXT: %var = alloca i8, i32 4
; CHECK: call void @llvm.dbg.declare(metadata i8* %var, metadata !12, metadata !13), !dbg !14
define void @debug_declare_morecasts() {
%var = alloca i32, i32 2, align 8
%other_bc = bitcast i32* %var to i64*
%other_bc2 = bitcast i64* %other_bc to i16*
call void @llvm.dbg.declare(metadata i16* %other_bc2, metadata !15, metadata !13), !dbg !16
unreachable
}
; Ensure that the first arg to dbg.declare points to the alloca, not bitcasts
; CHECK-LABEL: define void @debug_declare_morecasts
; CHECK-NEXT: %var = alloca i8, i32 8, align 8
; CHECK: call void @llvm.dbg.declare(metadata i8* %var, metadata !15, metadata !13), !dbg !16
define void @debug_declare_inttoptr() {
%var = alloca i32, i32 2, align 8
%i = ptrtoint i32* %var to i32
%p = inttoptr i32 %i to i8*
call void @llvm.dbg.declare(metadata i8* %p, metadata !15, metadata !13), !dbg !16
unreachable
}
; Ensure that we can look through ptrtoint/inttoptr
; CHECK-LABEL: define void @debug_declare_inttoptr
; CHECK-NEXT: alloca i8, i32 8, align 8
; CHECK: call void @llvm.dbg.declare(metadata i8* %var, metadata !15, metadata !13), !dbg !16
declare i8* @foo()
define void @debug_declare_noalloca() {
%call = tail call i8* @foo()
%config_.i.i = getelementptr inbounds i8, i8* %call, i32 104, !dbg !16
%bc = bitcast i8* %config_.i.i to i16*, !dbg !16
tail call void @llvm.dbg.declare(metadata i16* %bc, metadata !15, metadata !13), !dbg !16
unreachable
}
; Don't modify dbg.declares which don't ultimately point to an alloca.
; CHECK-LABEL: define void @debug_declare_noalloca()
; CHECK: call void @llvm.dbg.declare(metadata i16* %bc, metadata !15, metadata !13), !dbg !16
!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!9, !10}
!llvm.ident = !{!11}
; CHECK: !4 = !MDSubprogram(name: "debug_declare", scope: !1, file: !1, line: 1, type: !5, isLocal: false, isDefinition: true, scopeLine: 1, flags: DIFlagPrototyped, isOptimized: false, function: void ()* @debug_declare, variables: !2)
!0 = !MDCompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 3.7.0 (trunk 235150) (llvm/trunk 235152)", isOptimized: false, runtimeVersion: 0, emissionKind: 1, enums: !2, retainedTypes: !2, subprograms: !3, globals: !2, imports: !2)
!1 = !MDFile(filename: "foo.c", directory: "/s/llvm/cmakebuild")
!2 = !{}
!3 = !{!4, !8}
!4 = !MDSubprogram(name: "debug_declare", scope: !1, file: !1, line: 1, type: !5, isLocal: false, isDefinition: true, scopeLine: 1, flags: DIFlagPrototyped, isOptimized: false, function: void ()* @debug_declare, variables: !2)
!5 = !MDSubroutineType(types: !6)
!6 = !{null, !7}
!7 = !MDBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
!8 = !MDSubprogram(name: "debug_declare_morecasts", scope: !1, file: !1, line: 8, type: !5, isLocal: false, isDefinition: true, scopeLine: 8, flags: DIFlagPrototyped, isOptimized: false, function: void ()* @debug_declare_morecasts, variables: !2)
!9 = !{i32 2, !"Dwarf Version", i32 4}
!10 = !{i32 2, !"Debug Info Version", i32 3}
!11 = !{!"clang version 3.7.0 (trunk 235150) (llvm/trunk 235152)"}
!12 = !MDLocalVariable(tag: DW_TAG_arg_variable, name: "val", arg: 1, scope: !4, file: !1, line: 1, type: !7)
!13 = !MDExpression()
!14 = !MDLocation(line: 1, column: 24, scope: !4)
!15 = !MDLocalVariable(tag: DW_TAG_arg_variable, name: "var", arg: 1, scope: !8, file: !1, line: 9, type: !7)
!16 = !MDLocation(line: 9, column: 24, scope: !8)