Index: lib/CodeGen/CGStmt.cpp =================================================================== --- lib/CodeGen/CGStmt.cpp +++ lib/CodeGen/CGStmt.cpp @@ -1884,6 +1884,12 @@ ResultRegDests, AsmString, S.getNumOutputs()); SawAsmBlock = true; } + + // If the assembly contains any labels, mark the function noinline. Inlining + // it could cause the callee to contain the same ASM label twice (PR23715). + // This is pretty hacky, but it works. + if (AsmString.find("__MSASMLABEL_") != std::string::npos) + CurFn->addFnAttr(llvm::Attribute::NoInline); } for (unsigned i = 0, e = S.getNumInputs(); i != e; i++) { Index: test/CodeGen/ms-inline-asm.c =================================================================== --- test/CodeGen/ms-inline-asm.c +++ test/CodeGen/ms-inline-asm.c @@ -533,7 +533,7 @@ label: jmp label } - // CHECK-LABEL: define void @label1 + // CHECK: define void @label1() [[ATTR1:#[0-9]+]] { // CHECK: call void asm sideeffect inteldialect "{{.*}}__MSASMLABEL_.1__label:\0A\09jmp {{.*}}__MSASMLABEL_.1__label", "~{dirflag},~{fpsr},~{flags}"() } @@ -581,3 +581,6 @@ } // CHECK-LABEL: define i32 @test_indirect_field( // CHECK: call i32 asm sideeffect inteldialect "mov eax, dword ptr $1", + +// Functions with inline asm containing labels should be noinline (PR23715) +// CHECK: attributes [[ATTR1]] = { {{.*}}noinline{{.*}} }