diff --git a/llvm/lib/CodeGen/TailDuplicator.cpp b/llvm/lib/CodeGen/TailDuplicator.cpp --- a/llvm/lib/CodeGen/TailDuplicator.cpp +++ b/llvm/lib/CodeGen/TailDuplicator.cpp @@ -781,6 +781,9 @@ return false; if (!PredCond.empty()) return false; + for (MachineInstr &I : *TailBB) + if (I.getOpcode() == TargetOpcode::INLINEASM_BR) + return false; return true; } diff --git a/llvm/test/CodeGen/ARM/taildup.ll b/llvm/test/CodeGen/ARM/taildup.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/ARM/taildup.ll @@ -0,0 +1,55 @@ +; RUN: llc -mtriple=arm-linux-gnueabi -print-machineinstrs=tailduplication %s \ +; RUN: -o /dev/null 2>&1 | FileCheck %s + +; Check that INLINEASM_BR did not get duplicated into the previously duplicated +; blocks. Test case is a c-reduced then bugpointed sound/soc/ti/davinci-i2s.c +; from the Linux kernel. + +; CHECK: bb.2.if.else: +; CHECK: INLINEASM &"str $1, $0" [sideeffect] [mayload] [attdialect], $0:[mem:Q], killed renamable $r0, $1:[reguse:GPR], killed renamable $r1, !7 +; CHECK: bb.3.if.end: +; CHECK: INLINEASM_BR &"" [sideeffect] [attdialect], $0:[imm], blockaddress(@f, %ir-block.g), !8 + +@a = external dso_local local_unnamed_addr global i32*, align 4 +@c = external dso_local local_unnamed_addr global i32, align 4 + +define dso_local i32 @f() #0 { +entry: + %0 = load i32, i32* @c, align 4, !tbaa !1 + %tobool = icmp eq i32 %0, 0 + %1 = load i32*, i32** @a, align 4, !tbaa !5 + br i1 %tobool, label %if.else, label %if.then + +if.then: ; preds = %entry + tail call void asm sideeffect "str $1, $0", "*Qo,r"(i32* %1, i32 1) #1, !srcloc !7 + br label %if.end + +if.else: ; preds = %entry + tail call void asm sideeffect "str $1, $0", "*Qo,r"(i32* %1, i32 0) #1, !srcloc !7 + br label %if.end + +if.end: ; preds = %if.else, %if.then + callbr void asm sideeffect "", "X"(i8* blockaddress(@f, %g)) #1 + to label %asm.fallthrough [label %g], !srcloc !8 + +asm.fallthrough: ; preds = %if.end + unreachable + +g: ; preds = %if.end + ret i32 undef +} + +attributes #0 = { "use-soft-float"="false" } +attributes #1 = { nounwind } + +!llvm.ident = !{!0} + +!0 = !{!"clang version 9.0.0 (https://github.com/llvm/llvm-project.git 566858581206d1d7c0fd61886b11292c8ddce80b)"} +!1 = !{!2, !2, i64 0} +!2 = !{!"int", !3, i64 0} +!3 = !{!"omnipotent char", !4, i64 0} +!4 = !{!"Simple C/C++ TBAA"} +!5 = !{!6, !6, i64 0} +!6 = !{!"any pointer", !3, i64 0} +!7 = !{i32 27} +!8 = !{i32 118}