1;; Test for !DIStringType.!DIStringType is used to construct a Fortran 2;; CHARACTER intrinsic type, with a LEN type parameter where LEN is a 3;; dynamic parameter as in a deferred-length CHARACTER. LLVM after 4;; processing !DIStringType metadata in either of the following forms, 5;; generates DW_AT_string_length attribute 6;; !DIStringType(name: "character(*)", stringLength: !{{[0-9]+}}) 7;; !DIStringType(name: "character(*)", stringLengthExpr: !DIExpression(...)) 8;; 9;; !DIStringType has an optional stringLocationExpr field. This 10;; tests also verifies that field gets emitted as DW_AT_data_location 11;; in the DIE. 12 13; RUN: llc -filetype=obj %s -o - | llvm-dwarfdump - | FileCheck %s 14; CHECK: DW_TAG_string_type 15; CHECK: DW_AT_name (".str.DEFERRED") 16; CHECK-NEXT: DW_AT_string_length (DW_OP_push_object_address, DW_OP_plus_uconst 0x8) 17; CHECK-NEXT: DW_AT_data_location (DW_OP_push_object_address, DW_OP_deref) 18; CHECK: DW_TAG_string_type 19; CHECK: DW_AT_name ("character(*)!2") 20; CHECK-NEXT: DW_AT_string_length 21 22;; sample fortran testcase involving deferred and assumed length string types. 23;; program assumedLength 24;; character(len=:), allocatable :: deferred 25;; allocate(character(10)::deferred) 26;; call sub('Hello') 27;; call sub('Goodbye') 28;; contains 29;; subroutine sub(string) 30;; implicit none 31;; character(len=*), intent(in) :: string 32;; print *, string 33;; end subroutine sub 34;; end program assumedLength 35 36; ModuleID = 'distring.f90' 37source_filename = "distring.f90" 38target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" 39target triple = "x86_64-unknown-linux-gnu" 40 41%"QNCA_a0$ptr$rank0$" = type { ptr, i64, i64, i64, i64, i64 } 42 43@0 = internal unnamed_addr constant [7 x i8] c"Goodbye" 44@1 = internal unnamed_addr constant [5 x i8] c"Hello" 45@"assumedlength_$DEFERRED" = internal global %"QNCA_a0$ptr$rank0$" zeroinitializer, !dbg !0 46@2 = internal unnamed_addr constant i32 2 47 48; Function Attrs: noinline nounwind uwtable 49define void @MAIN__() #0 !dbg !2 { 50alloca_0: 51 %"var$1" = alloca [8 x i64], align 8 52 %"var$2" = alloca i64, align 8 53 %strlit = load [7 x i8], ptr @0, align 1 54 %strlit1 = load [5 x i8], ptr @1, align 1 55 %func_result = call i32 @for_set_reentrancy(ptr @2), !dbg !12 56 %val_fetch = load i64, ptr getelementptr inbounds (%"QNCA_a0$ptr$rank0$", ptr @"assumedlength_$DEFERRED", i32 0, i32 1), align 1, !dbg !13 57 %val_fetch4 = load i64, ptr getelementptr inbounds (%"QNCA_a0$ptr$rank0$", ptr @"assumedlength_$DEFERRED", i32 0, i32 3), align 1, !dbg !13 58 %and = and i64 %val_fetch4, 256, !dbg !13 59 %lshr = lshr i64 %and, 8, !dbg !13 60 %shl = shl i64 %lshr, 8, !dbg !13 61 %or = or i64 133, %shl, !dbg !13 62 %and5 = and i64 %val_fetch4, 1030792151040, !dbg !13 63 %lshr6 = lshr i64 %and5, 36, !dbg !13 64 %and7 = and i64 %or, -1030792151041, !dbg !13 65 %shl8 = shl i64 %lshr6, 36, !dbg !13 66 %or9 = or i64 %and7, %shl8, !dbg !13 67 store i64 %or9, ptr getelementptr inbounds (%"QNCA_a0$ptr$rank0$", ptr @"assumedlength_$DEFERRED", i32 0, i32 3), align 1, !dbg !13 68 store i64 10, ptr getelementptr inbounds (%"QNCA_a0$ptr$rank0$", ptr @"assumedlength_$DEFERRED", i32 0, i32 1), align 1, !dbg !13 69 store i64 0, ptr getelementptr inbounds (%"QNCA_a0$ptr$rank0$", ptr @"assumedlength_$DEFERRED", i32 0, i32 4), align 1, !dbg !13 70 store i64 0, ptr getelementptr inbounds (%"QNCA_a0$ptr$rank0$", ptr @"assumedlength_$DEFERRED", i32 0, i32 2), align 1, !dbg !13 71 %val_fetch10 = load i64, ptr getelementptr inbounds (%"QNCA_a0$ptr$rank0$", ptr @"assumedlength_$DEFERRED", i32 0, i32 3), align 1, !dbg !13 72 %val_fetch11 = load i64, ptr getelementptr inbounds (%"QNCA_a0$ptr$rank0$", ptr @"assumedlength_$DEFERRED", i32 0, i32 3), align 1, !dbg !13 73 %and12 = and i64 %val_fetch11, -68451041281, !dbg !13 74 %or13 = or i64 %and12, 1073741824, !dbg !13 75 store i64 %or13, ptr getelementptr inbounds (%"QNCA_a0$ptr$rank0$", ptr @"assumedlength_$DEFERRED", i32 0, i32 3), align 1, !dbg !13 76 %and14 = and i64 %val_fetch10, 1, !dbg !13 77 %shl15 = shl i64 %and14, 1, !dbg !13 78 %int_zext = trunc i64 %shl15 to i32, !dbg !13 79 %or16 = or i32 0, %int_zext, !dbg !13 80 %and17 = and i32 %or16, -17, !dbg !13 81 %and18 = and i64 %val_fetch10, 256, !dbg !13 82 %lshr19 = lshr i64 %and18, 8, !dbg !13 83 %and20 = and i32 %and17, -2097153, !dbg !13 84 %shl21 = shl i64 %lshr19, 21, !dbg !13 85 %int_zext22 = trunc i64 %shl21 to i32, !dbg !13 86 %or23 = or i32 %and20, %int_zext22, !dbg !13 87 %and24 = and i64 %val_fetch10, 1030792151040, !dbg !13 88 %lshr25 = lshr i64 %and24, 36, !dbg !13 89 %and26 = and i32 %or23, -31457281, !dbg !13 90 %shl27 = shl i64 %lshr25, 21, !dbg !13 91 %int_zext28 = trunc i64 %shl27 to i32, !dbg !13 92 %or29 = or i32 %and26, %int_zext28, !dbg !13 93 %and30 = and i64 %val_fetch10, 1099511627776, !dbg !13 94 %lshr31 = lshr i64 %and30, 40, !dbg !13 95 %and32 = and i32 %or29, -33554433, !dbg !13 96 %shl33 = shl i64 %lshr31, 25, !dbg !13 97 %int_zext34 = trunc i64 %shl33 to i32, !dbg !13 98 %or35 = or i32 %and32, %int_zext34, !dbg !13 99 %and36 = and i32 %or35, -2031617, !dbg !13 100 %or37 = or i32 %and36, 262144, !dbg !13 101 %func_result3 = call i32 @for_alloc_allocatable(i64 10, ptr @"assumedlength_$DEFERRED", i32 %or37), !dbg !13 102 call void @assumedlength_IP_sub_(ptr @1, i64 5), !dbg !14 103 call void @assumedlength_IP_sub_(ptr @0, i64 7), !dbg !15 104 ret void, !dbg !16 105} 106 107; Function Attrs: noinline nounwind uwtable 108define void @assumedlength_IP_sub_(ptr noalias nocapture readonly %STRING, i64 %"STRING.len$val") #0 !dbg !17 { 109alloca_1: 110 %"var$3" = alloca [8 x i64], align 8 111 %STRING.len = alloca i64, align 8, !dbg !23 112 %"var$4" = alloca i32, align 4, !dbg !23 113 %"(&)val$" = alloca [4 x i8], align 1, !dbg !23 114 %argblock = alloca { i64, ptr }, align 8, !dbg !23 115 call void @llvm.dbg.declare(metadata ptr %STRING.len, metadata !19, metadata !DIExpression()), !dbg !23 116 call void @llvm.dbg.declare(metadata ptr %STRING, metadata !21, metadata !DIExpression()), !dbg !24 117 store i64 %"STRING.len$val", ptr %STRING.len, align 8 118 %strlit = load [7 x i8], ptr @0, align 1, !dbg !25 119 %strlit1 = load [5 x i8], ptr @1, align 1, !dbg !25 120 %STRING.len_fetch = load i64, ptr %STRING.len, align 1, !dbg !26 121 store [4 x i8] c"8\04\01\00", ptr %"(&)val$", align 1, !dbg !26 122 %BLKFIELD_ = getelementptr inbounds { i64, ptr }, ptr %argblock, i32 0, i32 0, !dbg !26 123 store i64 %STRING.len_fetch, ptr %BLKFIELD_, align 1, !dbg !26 124 %BLKFIELD_3 = getelementptr inbounds { i64, ptr }, ptr %argblock, i32 0, i32 1, !dbg !26 125 store ptr %STRING, ptr %BLKFIELD_3, align 1, !dbg !26 126 %func_result = call i32 (ptr, i32, i64, ptr, ptr, ...) @for_write_seq_lis(ptr %"var$3", i32 -1, i64 1239157112576, ptr %"(&)val$", ptr %argblock), !dbg !26 127 ret void, !dbg !27 128} 129 130declare i32 @for_set_reentrancy(ptr) 131 132declare i32 @for_alloc_allocatable(i64, ptr, i32) 133 134; Function Attrs: nofree nosync nounwind readnone speculatable willreturn 135declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 136 137declare i32 @for_write_seq_lis(ptr, i32, i64, ptr, ptr, ...) 138 139attributes #0 = { noinline nounwind uwtable "intel-lang"="fortran" "min-legal-vector-width"="0" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" } 140attributes #1 = { nofree nosync nounwind readnone speculatable willreturn } 141 142!llvm.module.flags = !{!10, !11} 143!llvm.dbg.cu = !{!6} 144!omp_offload.info = !{} 145 146!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) 147!1 = distinct !DIGlobalVariable(name: "deferred", linkageName: "assumedlength_$DEFERRED", scope: !2, file: !3, line: 2, type: !9, isLocal: true, isDefinition: true) 148!2 = distinct !DISubprogram(name: "assumedlength", linkageName: "MAIN__", scope: !3, file: !3, line: 1, type: !4, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !7) 149!3 = !DIFile(filename: "distring.f90", directory: "/iusers/cchen15/examples/tests") 150!4 = !DISubroutineType(types: !5) 151!5 = !{null} 152!6 = distinct !DICompileUnit(language: DW_LANG_Fortran95, file: !3, producer: "Intel(R) Fortran 21.0-2142", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !7, globals: !8, splitDebugInlining: false, nameTableKind: None) 153!7 = !{} 154!8 = !{!0} 155!9 = !DIStringType(name: ".str.DEFERRED", stringLengthExpression: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 8), stringLocationExpression: !DIExpression(DW_OP_push_object_address, DW_OP_deref)) 156!10 = !{i32 2, !"Debug Info Version", i32 3} 157!11 = !{i32 2, !"Dwarf Version", i32 4} 158!12 = !DILocation(line: 1, column: 9, scope: !2) 159!13 = !DILocation(line: 3, column: 3, scope: !2) 160!14 = !DILocation(line: 4, column: 8, scope: !2) 161!15 = !DILocation(line: 5, column: 8, scope: !2) 162!16 = !DILocation(line: 6, column: 3, scope: !2) 163!17 = distinct !DISubprogram(name: "sub", linkageName: "assumedlength_IP_sub_", scope: !3, file: !3, line: 7, type: !4, scopeLine: 7, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !18) 164!18 = !{!19, !21} 165!19 = !DILocalVariable(name: "STRING.len", scope: !17, type: !20, flags: DIFlagArtificial) 166!20 = !DIBasicType(name: "INTEGER*8", size: 64, encoding: DW_ATE_signed) 167!21 = !DILocalVariable(name: "string", arg: 1, scope: !17, file: !3, line: 7, type: !22) 168!22 = !DIStringType(name: "character(*)!2", stringLength: !19) 169!23 = !DILocation(line: 0, scope: !17) 170!24 = !DILocation(line: 7, column: 18, scope: !17) 171!25 = !DILocation(line: 7, column: 14, scope: !17) 172!26 = !DILocation(line: 10, column: 11, scope: !17) 173!27 = !DILocation(line: 11, column: 3, scope: !17) 174