Index: lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp =================================================================== --- lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp +++ lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp @@ -309,6 +309,8 @@ // Local expression tree should go after the BLOCK. for (auto I = Header->getFirstTerminator(), E = Header->begin(); I != E; --I) { + if (std::prev(I)->isDebugInstr() || std::prev(I)->isPosition()) + continue; if (WebAssembly::isChild(*std::prev(I), MFI)) AfterSet.insert(&*std::prev(I)); else @@ -531,6 +533,8 @@ // Local expression tree should go after the TRY. for (auto I = Header->getFirstTerminator(), E = Header->begin(); I != E; --I) { + if (std::prev(I)->isDebugInstr() || std::prev(I)->isPosition()) + continue; if (WebAssembly::isChild(*std::prev(I), MFI)) AfterSet.insert(&*std::prev(I)); else Index: test/CodeGen/WebAssembly/cfg-stackify-dbg-skip.mir =================================================================== --- /dev/null +++ test/CodeGen/WebAssembly/cfg-stackify-dbg-skip.mir @@ -0,0 +1,255 @@ +# RUN: llc -mtriple=wasm32-unknown-unknown -run-pass wasm-cfg-stackify %s -o - | FileCheck %s + + +# The test checks if "block" instruction was not inserted inside group of +# of instructions that form a logical expression. In this case, the test +# instructions contain DBG_VALUE between them. + +--- | + ; ModuleID = 'test/CodeGen/WebAssembly/cfg-stackify-dbg-skip.ll' + source_filename = "foo.3a1fbbbh-cgu.0" + target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" + target triple = "wasm32-unknown-unknown" + + ; Function Attrs: nounwind + define {}* @foo({ i8*, i32 }* nocapture, i32, i64) local_unnamed_addr #0 { + start: + %tmp.sroa.0.0.extract.trunc.i.i.i.i.i = trunc i64 %2 to i32 + call void @llvm.dbg.value(metadata i32 %tmp.sroa.0.0.extract.trunc.i.i.i.i.i, metadata !34, metadata !DIExpression(DW_OP_LLVM_fragment, 0, 32)), !dbg !48 + %.sroa_cast1.i.i = bitcast { i8*, i32 }* %0 to i32*, !dbg !105 + store i32 0, i32* %.sroa_cast1.i.i, align 4 + %3 = icmp eq i32 %tmp.sroa.0.0.extract.trunc.i.i.i.i.i, 0 + br i1 %3, label %bb9, label %bb2 + + bb2: ; preds = %start + %tmp.sroa.4.0.extract.shift.i.i.i.i.i = lshr i64 %2, 32 + %tmp.sroa.4.0.extract.trunc.i.i.i.i.i = trunc i64 %tmp.sroa.4.0.extract.shift.i.i.i.i.i to i32 + %4 = tail call i8* @malloc(i32 8) + %5 = getelementptr inbounds i8, i8* %4, i32 4 + %6 = bitcast i8* %5 to i32* + store i32 %tmp.sroa.4.0.extract.trunc.i.i.i.i.i, i32* %6, align 4 + %7 = bitcast i8* %4 to {}* + br label %bb9 + + bb9: ; preds = %bb2, %start + %data.sroa.0.0 = phi {}* [ %7, %bb2 ], [ inttoptr (i32 1 to {}*), %start ] + ret {}* %data.sroa.0.0 + } + + ; Function Attrs: nounwind + declare noalias i8* @malloc(i32) unnamed_addr #0 + + ; Function Attrs: nounwind readnone speculatable + declare void @llvm.dbg.value(metadata, metadata, metadata) #1 + + ; Function Attrs: nounwind + declare void @llvm.stackprotector(i8*, i8**) #0 + + attributes #0 = { nounwind } + attributes #1 = { nounwind readnone speculatable } + + !llvm.dbg.cu = !{!0} + !llvm.module.flags = !{!33} + + !0 = distinct !DICompileUnit(language: DW_LANG_Rust, file: !1, producer: "clang LLVM (rustc version 1.30.0-dev)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, globals: !3) + !1 = !DIFile(filename: "foo.rs", directory: "/misc/coresimd") + !2 = !{} + !3 = !{!4, !29, !31} + !4 = !DIGlobalVariableExpression(var: !5, expr: !DIExpression()) + !5 = distinct !DIGlobalVariable(name: "vtable", scope: null, file: !6, type: !7, isLocal: true, isDefinition: true) + !6 = !DIFile(filename: "", directory: "") + !7 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "vtable", file: !6, align: 32, flags: DIFlagArtificial, elements: !2, vtableHolder: !8, identifier: "vtable") + !8 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "PanicPayload<&str>", scope: !9, file: !6, size: 64, align: 32, elements: !12, identifier: "f20029ab88f79681a6fb4031dc880864") + !9 = !DINamespace(name: "begin_panic", scope: !10) + !10 = !DINamespace(name: "panicking", scope: !11) + !11 = !DINamespace(name: "std", scope: null) + !12 = !{!13} + !13 = !DIDerivedType(tag: DW_TAG_member, name: "inner", scope: !8, file: !6, baseType: !14, size: 64, align: 32) + !14 = distinct !DICompositeType(tag: DW_TAG_union_type, name: "Option<&str>", scope: !15, file: !6, size: 64, align: 32, elements: !17, identifier: "fa309c24fa29eafa7eabc3e820fdb228") + !15 = !DINamespace(name: "option", scope: !16) + !16 = !DINamespace(name: "core", scope: null) + !17 = !{!18} + !18 = !DIDerivedType(tag: DW_TAG_member, name: "RUST$ENCODED$ENUM$0$None", scope: !14, file: !6, baseType: !19, size: 64, align: 32) + !19 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Some", scope: !15, file: !6, size: 64, align: 32, elements: !20, identifier: "fa309c24fa29eafa7eabc3e820fdb228::Some") + !20 = !{!21} + !21 = !DIDerivedType(tag: DW_TAG_member, name: "__0", scope: !19, file: !6, baseType: !22, size: 64, align: 32) + !22 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "&str", file: !6, size: 64, align: 32, elements: !23, identifier: "111094d970b097647de579f9c509ef08") + !23 = !{!24, !27} + !24 = !DIDerivedType(tag: DW_TAG_member, name: "data_ptr", scope: !22, file: !6, baseType: !25, size: 32, align: 32) + !25 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "*const u8", baseType: !26, size: 32, align: 32) + !26 = !DIBasicType(name: "u8", size: 8, encoding: DW_ATE_unsigned) + !27 = !DIDerivedType(tag: DW_TAG_member, name: "length", scope: !22, file: !6, baseType: !28, size: 32, align: 32, offset: 32) + !28 = !DIBasicType(name: "usize", size: 32, encoding: DW_ATE_unsigned) + !29 = !DIGlobalVariableExpression(var: !30, expr: !DIExpression()) + !30 = distinct !DIGlobalVariable(name: "vtable", scope: null, file: !6, type: !7, isLocal: true, isDefinition: true) + !31 = !DIGlobalVariableExpression(var: !32, expr: !DIExpression()) + !32 = distinct !DIGlobalVariable(name: "vtable", scope: null, file: !6, type: !7, isLocal: true, isDefinition: true) + !33 = !{i32 2, !"Debug Info Version", i32 3} + !34 = !DILocalVariable(name: "z", scope: !35, file: !36, line: 357, type: !14, align: 4) + !35 = distinct !DILexicalBlock(scope: !37, file: !36, line: 357, column: 8) + !36 = !DIFile(filename: "/misc/libcore/ptr.rs", directory: "") + !37 = distinct !DISubprogram(name: "swap_nonoverlapping_one>", linkageName: "_ZN4core3ptr23swap_nonoverlapping_one17h9b13106d1b81ade4E", scope: !38, file: !36, line: 353, type: !39, isLocal: true, isDefinition: true, scopeLine: 353, flags: DIFlagPrototyped, isOptimized: true, unit: !0, templateParams: !46, retainedNodes: !42) + !38 = !DINamespace(name: "ptr", scope: !16) + !39 = !DISubroutineType(types: !40) + !40 = !{null, !41, !41} + !41 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "*mut core::option::Option<&str>", baseType: !14, size: 32, align: 32) + !42 = !{!43, !45, !34} + !43 = !DILocalVariable(name: "x", arg: 1, scope: !37, file: !44, line: 1, type: !41) + !44 = !DIFile(filename: "foo.rs", directory: "") + !45 = !DILocalVariable(name: "y", arg: 2, scope: !37, file: !44, line: 1, type: !41) + !46 = !{!47} + !47 = !DITemplateTypeParameter(name: "T", type: !14) + !48 = !DILocation(line: 357, column: 12, scope: !35, inlinedAt: !49) + !49 = distinct !DILocation(line: 637, column: 8, scope: !50, inlinedAt: !60) + !50 = distinct !DILexicalBlock(scope: !52, file: !51, line: 636, column: 4) + !51 = !DIFile(filename: "/misc/libcore/mem.rs", directory: "") + !52 = distinct !DISubprogram(name: "swap>", linkageName: "_ZN4core3mem4swap17hf525fca8ad6e588dE", scope: !53, file: !51, line: 635, type: !54, isLocal: true, isDefinition: true, scopeLine: 635, flags: DIFlagPrototyped, isOptimized: true, unit: !0, templateParams: !46, retainedNodes: !57) + !53 = !DINamespace(name: "mem", scope: !16) + !54 = !DISubroutineType(types: !55) + !55 = !{null, !56, !56} + !56 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "&mut core::option::Option<&str>", baseType: !14, size: 32, align: 32) + !57 = !{!58, !59} + !58 = !DILocalVariable(name: "x", arg: 1, scope: !52, file: !44, line: 1, type: !56) + !59 = !DILocalVariable(name: "y", arg: 2, scope: !52, file: !44, line: 1, type: !56) + !60 = distinct !DILocation(line: 695, column: 4, scope: !61, inlinedAt: !67) + !61 = distinct !DISubprogram(name: "replace>", linkageName: "_ZN4core3mem7replace17he6f7041b81a6d845E", scope: !53, file: !51, line: 694, type: !62, isLocal: true, isDefinition: true, scopeLine: 694, flags: DIFlagPrototyped, isOptimized: true, unit: !0, templateParams: !46, retainedNodes: !64) + !62 = !DISubroutineType(types: !63) + !63 = !{!14, !56, !14} + !64 = !{!65, !66} + !65 = !DILocalVariable(name: "dest", arg: 1, scope: !61, file: !44, line: 1, type: !56) + !66 = !DILocalVariable(name: "src", arg: 2, scope: !61, file: !44, line: 1, type: !14) + !67 = distinct !DILocation(line: 858, column: 8, scope: !68, inlinedAt: !76) + !68 = distinct !DISubprogram(name: "take<&str>", linkageName: "_ZN38_$LT$core..option..Option$LT$T$GT$$GT$4take17ha569a64f962bb285E", scope: !14, file: !69, line: 857, type: !70, isLocal: true, isDefinition: true, scopeLine: 857, flags: DIFlagPrototyped, isOptimized: true, unit: !0, templateParams: !74, retainedNodes: !72) + !69 = !DIFile(filename: "/misc/libcore/option.rs", directory: "") + !70 = !DISubroutineType(types: !71) + !71 = !{!14, !56} + !72 = !{!73} + !73 = !DILocalVariable(name: "self", arg: 1, scope: !68, file: !44, line: 1, type: !56) + !74 = !{!75} + !75 = !DITemplateTypeParameter(name: "T", type: !22) + !76 = distinct !DILocation(line: 425, column: 29, scope: !77) + !77 = distinct !DISubprogram(name: "box_me_up<&str>", linkageName: "_ZN91_$LT$std..panicking..begin_panic..PanicPayload$LT$A$GT$$u20$as$u20$core..panic..BoxMeUp$GT$9box_me_up17h0db1ddc6159c8fb6E", scope: !79, file: !78, line: 424, type: !80, isLocal: true, isDefinition: true, scopeLine: 424, flags: DIFlagPrototyped, isOptimized: true, unit: !0, templateParams: !103, retainedNodes: !93) + !78 = !DIFile(filename: "/misc/libstd/panicking.rs", directory: "") + !79 = !DINamespace(name: "{{impl}}", scope: !9) + !80 = !DISubroutineType(types: !81) + !81 = !{!82, !92} + !82 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "*mut Any", scope: !83, file: !6, size: 64, align: 32, elements: !84, identifier: "53372fa6cb48d0d4ed09ef2b1dc9567c") + !83 = !DINamespace(name: "any", scope: !16) + !84 = !{!85, !87} + !85 = !DIDerivedType(tag: DW_TAG_member, name: "pointer", scope: !82, file: !6, baseType: !86, size: 32, align: 32, flags: DIFlagArtificial) + !86 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "*mut u8", baseType: !26, size: 32, align: 32) + !87 = !DIDerivedType(tag: DW_TAG_member, name: "vtable", scope: !82, file: !6, baseType: !88, size: 32, align: 32, offset: 32, flags: DIFlagArtificial) + !88 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "&[usize; 3]", baseType: !89, size: 32, align: 32) + !89 = !DICompositeType(tag: DW_TAG_array_type, baseType: !28, size: 96, align: 32, elements: !90) + !90 = !{!91} + !91 = !DISubrange(count: 3) + !92 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "&mut std::panicking::begin_panic::PanicPayload<&str>", baseType: !8, size: 32, align: 32) + !93 = !{!94, !95, !101} + !94 = !DILocalVariable(name: "self", arg: 1, scope: !77, file: !44, line: 1, type: !92) + !95 = !DILocalVariable(name: "data", scope: !96, file: !78, line: 425, type: !97, align: 4) + !96 = distinct !DILexicalBlock(scope: !77, file: !78, line: 425, column: 12) + !97 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Box", scope: !83, file: !6, size: 64, align: 32, elements: !98, identifier: "9e5777c3b641846cf0b3f45ae396cc20") + !98 = !{!99, !100} + !99 = !DIDerivedType(tag: DW_TAG_member, name: "pointer", scope: !97, file: !6, baseType: !86, size: 32, align: 32, flags: DIFlagArtificial) + !100 = !DIDerivedType(tag: DW_TAG_member, name: "vtable", scope: !97, file: !6, baseType: !88, size: 32, align: 32, offset: 32, flags: DIFlagArtificial) + !101 = !DILocalVariable(name: "a", scope: !102, file: !78, line: 426, type: !22, align: 4) + !102 = distinct !DILexicalBlock(scope: !77, file: !78, line: 426, column: 27) + !103 = !{!104} + !104 = !DITemplateTypeParameter(name: "A", type: !22) + !105 = !DILocation(line: 358, column: 8, scope: !35, inlinedAt: !49) + +... +--- +name: foo +alignment: 0 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +failedISel: false +tracksRegLiveness: false +registers: + - { id: 0, class: i32, preferred-register: '' } + - { id: 1, class: i32, preferred-register: '' } + - { id: 2, class: i64, preferred-register: '' } + - { id: 3, class: i32, preferred-register: '' } + - { id: 4, class: i32, preferred-register: '' } + - { id: 5, class: i32, preferred-register: '' } + - { id: 6, class: i32, preferred-register: '' } + - { id: 7, class: i64, preferred-register: '' } + - { id: 8, class: i64, preferred-register: '' } + - { id: 9, class: i32, preferred-register: '' } + - { id: 10, class: i32, preferred-register: '' } + - { id: 11, class: i32, preferred-register: '' } + - { id: 12, class: i32, preferred-register: '' } + - { id: 13, class: i64, preferred-register: '' } + - { id: 14, class: i64, preferred-register: '' } + - { id: 15, class: i32, preferred-register: '' } + - { id: 16, class: i32, preferred-register: '' } + - { id: 17, class: i32, preferred-register: '' } + - { id: 18, class: i32, preferred-register: '' } + - { id: 19, class: i32, preferred-register: '' } + - { id: 20, class: i32, preferred-register: '' } + - { id: 21, class: i32, preferred-register: '' } + - { id: 22, class: i64, preferred-register: '' } + - { id: 23, class: i64, preferred-register: '' } + - { id: 24, class: i32, preferred-register: '' } +liveins: + - { reg: '$arguments', virtual-reg: '' } + - { reg: '$value_stack', virtual-reg: '' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 0 + adjustsStack: false + hasCalls: true + stackProtector: '' + maxCallFrameSize: 0 + cvBytesOfCalleeSavedRegisters: 0 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + localFrameSize: 0 + savePoint: '' + restorePoint: '' +fixedStack: +stack: +constants: +body: | + bb.0.start: + successors: %bb.2(0x30000000), %bb.1(0x50000000) + + %21:i32 = GET_LOCAL_I32 0, implicit-def $arguments + %11:i32 = CONST_I32 0, implicit-def dead $arguments, implicit-def $value_stack, implicit $value_stack + STORE_I32 2, 0, %21, %11, implicit-def dead $arguments, implicit-def $value_stack, implicit $value_stack :: (store 4 into %ir..sroa_cast1.i.i) + %22:i64 = GET_LOCAL_I64 2, implicit-def $arguments + %18:i32 = I32_WRAP_I64 %22, implicit-def dead $arguments, implicit-def $value_stack, implicit $value_stack + DBG_VALUE debug-use %18, debug-use $noreg, !34, !DIExpression(DW_OP_LLVM_fragment, 0, 32), debug-location !48 + BR_UNLESS %bb.2, %18, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack + + bb.1.bb2: + %15:i32 = CONST_I32 8, implicit-def dead $arguments, implicit-def $value_stack, implicit $value_stack + %20:i32 = CALL_I32 @malloc, %15, implicit-def dead $arguments, implicit $sp32, implicit $sp64, implicit-def $value_stack, implicit $value_stack + %19:i32 = TEE_LOCAL_I32 0, %20, implicit-def $arguments + %23:i64 = GET_LOCAL_I64 2, implicit-def $arguments + %13:i64 = CONST_I64 32, implicit-def dead $arguments, implicit-def $value_stack, implicit $value_stack + %14:i64 = SHR_U_I64 %23, %13, implicit-def dead $arguments, implicit-def $value_stack, implicit $value_stack + STORE32_I64 2, 4, %19, %14, implicit-def dead $arguments, implicit-def $value_stack, implicit $value_stack :: (store 4 into %ir.6) + %24:i32 = GET_LOCAL_I32 0, implicit-def $arguments + RETURN_I32 %24, implicit-def dead $arguments + + bb.2: + %17:i32 = CONST_I32 1, implicit-def dead $arguments, implicit-def $value_stack, implicit $value_stack + RETURN_I32 %17, implicit-def dead $arguments, implicit-def $value_stack, implicit $value_stack + + ; CHECK: body: + ; CHECK: GET_LOCAL_I64 + ; CHECK-NEXT: I32_WRAP_I64 + ; CHECK-NEXT: DBG_VALUE + ; CHECK-NEXT: BLOCK + ; CHECK-NEXT: BR_UNLESS +...