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.ll =================================================================== --- /dev/null +++ test/CodeGen/WebAssembly/cfg-stackify-dbg-skip.ll @@ -0,0 +1,57 @@ +; RUN: llc %s -O2 -stop-before wasm-cfg-stackify -o - | FileCheck -check-prefix=CHECK-BEFORE %s +; RUN: llc %s -O2 -stop-after wasm-cfg-stackify -o - | FileCheck -check-prefix=CHECK-AFTER %s + +; The test checks if "block" instruction was not inserted inside group of +; of instructions that form a stackified expression. In this case, the test +; instructions contain DBG_VALUE between them. + +; CHECK-BEFORE: body: +; CHECK-BEFORE: GET_LOCAL_I64 +; CHECK-BEFORE-NEXT: I32_WRAP_I64 +; CHECK-BEFORE-NEXT: DBG_VALUE +; CHECK-BEFORE-NEXT: BR_UNLESS + +; CHECK-AFTER: body: +; CHECK-AFTER: BLOCK +; CHECK-AFTER-NEXT: GET_LOCAL_I64 +; CHECK-AFTER-NEXT: I32_WRAP_I64 +; CHECK-AFTER-NEXT: DBG_VALUE +; CHECK-AFTER-NEXT: BR_UNLESS + +target triple = "wasm32-unknown-unknown" +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 + %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 + call void @llvm.dbg.value(metadata i32 %tmp.sroa.0.0.extract.trunc.i.i.i.i.i, metadata !46, metadata !DIExpression(DW_OP_LLVM_fragment, 0, 32)), !dbg !105 + %4 = tail call i8* @malloc(i32 8) + %5 = getelementptr inbounds i8, i8* %4, i32 4 + %6 = bitcast i8* %5 to i32* + %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 +} +declare noalias i8* @malloc(i32) unnamed_addr #0 +declare void @llvm.dbg.value(metadata, metadata, metadata) #1 +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!33} +!0 = distinct !DICompileUnit(language: DW_LANG_Rust, file: !6, producer: "clang LLVM (rustc version 1.30.0-dev)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, globals: !3) +!2 = !{} +!3 = !{} +!6 = !DIFile(filename: "", directory: "") +!22 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "&str", file: !6, size: 64, align: 32, elements: !23, identifier: "111094d970b097647de579f9c509ef08") +!23 = !{} +!33 = !{i32 2, !"Debug Info Version", i32 3} +!35 = distinct !DILexicalBlock(scope: !37, file: !6, line: 357, column: 8) +!37 = distinct !DISubprogram(name: "foobar", linkageName: "_fooba", scope: !38, file: !6, line: 353, type: !39, isLocal: true, isDefinition: true, scopeLine: 353, flags: DIFlagPrototyped, isOptimized: true, unit: !0, templateParams: !47, retainedNodes: !42) +!38 = !DINamespace(name: "ptr", scope: null) +!39 = !DISubroutineType(types: !40) +!40 = !{} +!42 = !{!46} +!46 = !DILocalVariable(name: "z", scope: !35, file: !6, line: 357, type: !22, align: 4) +!47 = !{} +!105 = !DILocation(line: 357, column: 12, scope: !35)