diff --git a/llvm/lib/CodeGen/TargetInstrInfo.cpp b/llvm/lib/CodeGen/TargetInstrInfo.cpp --- a/llvm/lib/CodeGen/TargetInstrInfo.cpp +++ b/llvm/lib/CodeGen/TargetInstrInfo.cpp @@ -1579,10 +1579,6 @@ // Just go right to the target implementation. return getOutliningTypeImpl(MIT, Flags); - // Don't allow instructions that don't materialize to impact analysis. - if (MI.isMetaInstruction()) - return outliner::InstrType::Invisible; - // Be conservative about inline assembly. if (MI.isInlineAsm()) return outliner::InstrType::Illegal; @@ -1591,6 +1587,21 @@ if (MI.isLabel()) return outliner::InstrType::Illegal; + // Don't let debug instructions impact analysis. + if (MI.isDebugInstr()) + return outliner::InstrType::Invisible; + + // Some other special cases. + switch (MI.getOpcode()) { + case TargetOpcode::IMPLICIT_DEF: + case TargetOpcode::KILL: + case TargetOpcode::LIFETIME_START: + case TargetOpcode::LIFETIME_END: + return outliner::InstrType::Invisible; + default: + break; + } + // Is this a terminator for a basic block? if (MI.isTerminator()) { // If this is a branch to another block, we can't outline it. diff --git a/llvm/test/CodeGen/AArch64/machine-outliner-labels.ll b/llvm/test/CodeGen/AArch64/machine-outliner-labels.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/machine-outliner-labels.ll @@ -0,0 +1,509 @@ +; Test that we prevent labels from being outlined. This will crash otherwise. +; RUN: llc < %s -mtriple=arm64e-apple-macosx -filetype=obj %s -o %t.o +; RUN: llvm-objdump -D %t.o | FileCheck %s +; CHECK: <_eggs>: + +target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128" +target triple = "arm64e-apple-macosx" + +%zot = type { %ham } +%ham = type { [2 x i32] } + +; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) +declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #0 + +declare i32 @pluto(...) + +declare void @pluto.1() + +declare void @pluto.2() + +declare void @baz() + +declare void @hoge() + +; Function Attrs: cold +declare [2 x i64] @zot() #1 + +declare ptr @spam(ptr) + +declare i32 @hoge.3() + +; Function Attrs: minsize +define weak_odr void @widget(ptr %arg, ptr %arg1, ptr %arg2, ptr %arg3, i32 %arg4, ptr %arg5, ptr %arg6, ptr %arg7, i1 %arg8, i1 %arg9, i8 %arg10) #2 personality ptr @pluto { +bb: + %inst = zext i32 1 to i64 + br label %bb11 + +bb11: ; preds = %bb19, %bb + %inst12 = phi i64 [ 0, %bb ], [ %inst22, %bb19 ] + %inst13 = getelementptr i32, ptr null, i64 %inst12 + br i1 %arg8, label %bb16, label %bb15 + +bb14: ; preds = %bb44, %bb15 + ret void + +bb15: ; preds = %bb11 + store i8 0, ptr %arg, align 1 + br label %bb14 + +bb16: ; preds = %bb16, %bb11 + store i8 0, ptr %arg6, align 1 + %inst17 = load volatile [2 x i64], ptr null, align 8 + store i8 102, ptr %arg2, align 1 + %inst18 = icmp eq i64 0, 1 + br i1 %inst18, label %bb19, label %bb16 + +bb19: ; preds = %bb16 + %inst20 = load ptr, ptr %arg5, align 8 + %inst21 = call i1 %inst20(ptr %arg3, i32 0, i32 0) + %inst22 = or i64 %inst12, 1 + br i1 %arg8, label %bb23, label %bb11 + +bb23: ; preds = %bb19 + %inst24 = select i1 false, i1 false, i1 false + br label %bb25 + +bb25: ; preds = %bb54, %bb23 + %inst26 = load volatile i1, ptr %arg2, align 1 + br i1 %arg8, label %bb27, label %bb33 + +bb27: ; preds = %bb29, %bb25 + %inst28 = phi i64 [ 1, %bb29 ], [ 0, %bb25 ] + br label %bb31 + +bb29: ; preds = %bb31 + %inst30 = icmp eq i64 %inst28, %inst + br i1 %inst30, label %bb54, label %bb27 + +bb31: ; preds = %bb31, %bb27 + call void @pluto.1() + %inst32 = icmp eq i64 0, 0 + br i1 %inst32, label %bb29, label %bb31 + +bb33: ; preds = %bb25 + %inst34 = call i32 @hoge.3(ptr null, i32 0) + br label %bb35 + +bb35: ; preds = %bb41, %bb33 + %inst36 = icmp eq i8 %arg10, 0 + %inst37 = zext i32 %inst34 to i64 + %inst38 = getelementptr i8, ptr null, i64 %inst37 + %inst39 = load i8, ptr %inst38, align 1 + %inst40 = icmp eq i8 %inst39, 0 + br label %bb42 + +bb41: ; preds = %bb51 + br i1 %arg8, label %bb53, label %bb35 + +bb42: ; preds = %bb51, %bb35 + %inst43 = phi i64 [ 0, %bb35 ], [ %inst52, %bb51 ] + call void @pluto.1(ptr %arg1, i32 0, i32 0) + br i1 %inst36, label %bb47, label %bb46 + +bb44: ; preds = %bb47 + %inst45 = landingpad { ptr, i32 } + cleanup + br label %bb14 + +bb46: ; preds = %bb42 + call void @pluto.1(ptr %arg, i32 0, i32 0) + br label %bb47 + +bb47: ; preds = %bb46, %bb42 + invoke void @pluto.1(ptr null, i32 0, i32 0) + to label %bb48 unwind label %bb44 + +bb48: ; preds = %bb47 + br i1 %inst40, label %bb51, label %bb49 + +bb49: ; preds = %bb48 + %inst50 = getelementptr i32, ptr null, i64 %inst43 + br label %bb51 + +bb51: ; preds = %bb49, %bb48 + %inst52 = or i64 %inst43, 1 + br i1 %arg9, label %bb41, label %bb42 + +bb53: ; preds = %bb41 + call void @llvm.lifetime.start.p0(i64 0, ptr null) + br label %bb54 + +bb54: ; preds = %bb53, %bb29 + br i1 %arg9, label %bb25, label %bb55 + +bb55: ; preds = %bb54 + %inst56 = call ptr @spam(ptr null) + unreachable +} + +; Function Attrs: minsize +define weak_odr void @eggs(ptr %arg, ptr %arg1, ptr %arg2, ptr %arg3, i32 %arg4, i64 %arg5, i64 %arg6, ptr %arg7, i1 %arg8, i1 %arg9, i1 %arg10, i1 %arg11) #2 personality ptr @pluto { +bb: + %inst = alloca %zot, i32 0, align 4 + br label %bb12 + +bb12: ; preds = %bb19, %bb + br i1 %arg11, label %bb14, label %bb13 + +bb13: ; preds = %bb41, %bb12 + ret void + +bb14: ; preds = %bb17, %bb12 + store i8 1, ptr %arg3, align 1 + br i1 %arg9, label %bb15, label %bb17 + +bb15: ; preds = %bb14 + %inst16 = load ptr, ptr null, align 8 + br label %bb17 + +bb17: ; preds = %bb15, %bb14 + %inst18 = icmp eq i64 %arg5, %arg6 + br i1 %inst18, label %bb20, label %bb14 + +bb19: ; preds = %bb20 + br i1 %arg8, label %bb23, label %bb12 + +bb20: ; preds = %bb20, %bb17 + %inst21 = load ptr, ptr null, align 8 + %inst22 = call i1 %inst21(ptr null, i32 0, i32 0) + br i1 %arg10, label %bb19, label %bb20 + +bb23: ; preds = %bb50, %bb19 + br i1 %arg10, label %bb24, label %bb51 + +bb24: ; preds = %bb29, %bb23 + %inst25 = load i8, ptr null, align 1 + %inst26 = icmp eq i8 %inst25, 0 + call void @pluto.2() + br i1 %inst26, label %bb29, label %bb27 + +bb27: ; preds = %bb24 + %inst28 = load ptr, ptr null, align 8 + br label %bb29 + +bb29: ; preds = %bb27, %bb24 + br i1 %arg11, label %bb50, label %bb24 + +bb30: ; preds = %bb50 + %inst31 = call i32 @hoge.3(ptr null, i32 0) + br label %bb32 + +bb32: ; preds = %bb37, %bb30 + %inst33 = zext i32 %inst31 to i64 + %inst34 = getelementptr i8, ptr null, i64 %inst33 + %inst35 = load i8, ptr %inst34, align 1 + %inst36 = icmp eq i8 %inst35, 0 + br label %bb38 + +bb37: ; preds = %bb48 + br i1 %arg9, label %bb49, label %bb32 + +bb38: ; preds = %bb48, %bb32 + %inst39 = load i8, ptr %arg2, align 1 + %inst40 = icmp eq i8 %inst39, 0 + invoke void @pluto.2(ptr %arg, i32 0, i32 0) + to label %bb43 unwind label %bb41 + +bb41: ; preds = %bb38 + %inst42 = landingpad { ptr, i32 } + cleanup + br label %bb13 + +bb43: ; preds = %bb38 + call void @pluto.2(ptr null, i32 0, i32 0) + call void @pluto.2(ptr %arg1, i32 0, i32 0) + %inst44 = or i1 true, %inst40 + br i1 %inst44, label %bb46, label %bb45 + +bb45: ; preds = %bb43 + call void @pluto.2(ptr null, i32 0, i32 0) + unreachable + +bb46: ; preds = %bb43 + br i1 %inst36, label %bb48, label %bb47 + +bb47: ; preds = %bb46 + call void @pluto.2(ptr null, i32 0, i32 0) + unreachable + +bb48: ; preds = %bb46 + br i1 %arg8, label %bb37, label %bb38 + +bb49: ; preds = %bb37 + call void @llvm.lifetime.start.p0(i64 0, ptr null) + br label %bb50 + +bb50: ; preds = %bb49, %bb29 + br i1 %arg8, label %bb23, label %bb30 + +bb51: ; preds = %bb23 + %inst52 = call ptr @spam(ptr null) + unreachable +} + +; Function Attrs: minsize +define weak_odr void @baz.4(ptr %arg, ptr %arg1, ptr %arg2, ptr %arg3, i32 %arg4, i64 %arg5, i64 %arg6, i64 %arg7, i1 %arg8, i1 %arg9, i1 %arg10, ptr %arg11, i1 %arg12, i1 %arg13) #2 personality ptr @pluto { +bb: + %inst = alloca %zot, i32 0, align 4 + br label %bb14 + +bb14: ; preds = %bb17, %bb + br i1 %arg9, label %bb16, label %bb15 + +bb15: ; preds = %bb42, %bb14 + ret void + +bb16: ; preds = %bb16, %bb14 + store i8 0, ptr %arg3, align 1 + store i8 1, ptr %arg2, align 1 + br i1 %arg10, label %bb17, label %bb16 + +bb17: ; preds = %bb16 + %inst18 = load ptr, ptr null, align 8 + %inst19 = call i1 %inst18(ptr %arg11, i32 0, i32 0) + br i1 %arg8, label %bb20, label %bb14 + +bb20: ; preds = %bb50, %bb17 + br i1 %arg9, label %bb21, label %bb51 + +bb21: ; preds = %bb20 + br i1 %arg8, label %bb22, label %bb31 + +bb22: ; preds = %bb24, %bb21 + %inst23 = load ptr, ptr null, align 8 + br label %bb25 + +bb24: ; preds = %bb29 + br i1 %arg10, label %bb50, label %bb22 + +bb25: ; preds = %bb29, %bb22 + %inst26 = load i8, ptr null, align 1 + %inst27 = icmp eq i8 %inst26, 0 + call void @baz(ptr null, i32 0, i32 0) + br i1 %inst27, label %bb29, label %bb28 + +bb28: ; preds = %bb25 + store i32 0, ptr %arg, align 4 + br label %bb29 + +bb29: ; preds = %bb28, %bb25 + %inst30 = icmp eq i64 0, 0 + br i1 %inst30, label %bb24, label %bb25 + +bb31: ; preds = %bb50, %bb21 + %inst32 = invoke i32 @hoge.3(ptr null, i32 0) + to label %bb33 unwind label %bb42 + +bb33: ; preds = %bb39, %bb31 + %inst34 = phi i64 [ 1, %bb39 ], [ 0, %bb31 ] + %inst35 = zext i32 %inst32 to i64 + %inst36 = getelementptr i8, ptr null, i64 %inst35 + %inst37 = load i8, ptr %inst36, align 1 + %inst38 = icmp eq i8 %inst37, 0 + br label %bb41 + +bb39: ; preds = %bb48 + %inst40 = icmp eq i64 %inst34, 0 + br i1 %inst40, label %bb49, label %bb33 + +bb41: ; preds = %bb48, %bb33 + invoke void @baz(ptr %arg, i32 0, i32 0) + to label %bb44 unwind label %bb42 + +bb42: ; preds = %bb41, %bb31 + %inst43 = landingpad { ptr, i32 } + cleanup + br label %bb15 + +bb44: ; preds = %bb41 + call void @baz(ptr %arg1, i32 0, i32 0) + br i1 %arg12, label %bb46, label %bb45 + +bb45: ; preds = %bb44 + call void @baz(ptr null, i32 0, i32 0) + unreachable + +bb46: ; preds = %bb44 + br i1 %inst38, label %bb48, label %bb47 + +bb47: ; preds = %bb46 + call void @baz(ptr null, i32 0, i32 0) + unreachable + +bb48: ; preds = %bb46 + br i1 %arg13, label %bb39, label %bb41 + +bb49: ; preds = %bb39 + call void @llvm.lifetime.start.p0(i64 0, ptr null) + br label %bb50 + +bb50: ; preds = %bb49, %bb24 + br i1 %arg8, label %bb20, label %bb31 + +bb51: ; preds = %bb20 + %inst52 = call ptr @spam(ptr null) + unreachable +} + +; Function Attrs: minsize +define weak_odr void @barney(ptr %arg, ptr %arg1, ptr %arg2, ptr %arg3, i64 %arg4, i64 %arg5, i64 %arg6, ptr %arg7, i1 %arg8, i1 %arg9) #2 personality ptr @pluto { +bb: + %inst = alloca %zot, i32 0, align 4 + %inst10 = load i32, ptr null, align 8 + %inst11 = zext i32 %inst10 to i64 + %inst12 = call ptr @zot.5() + store i32 0, ptr %arg, align 4 + br label %bb13 + +bb13: ; preds = %bb27, %bb + %inst14 = phi i64 [ 0, %bb ], [ %arg4, %bb27 ] + %inst15 = load ptr, ptr %arg, align 8 + %inst16 = getelementptr i32, ptr %inst15, i64 %inst14 + %inst17 = load i32, ptr %inst16, align 4 + %inst18 = icmp eq i32 %inst17, 0 + br i1 %inst18, label %bb22, label %bb20 + +bb20: ; preds = %bb13 + %inst21 = call [2 x i64] @zot() + unreachable + +bb22: ; preds = %bb25, %bb13 + store i8 0, ptr %arg7, align 1 + br i1 %arg8, label %bb23, label %bb25 + +bb23: ; preds = %bb22 + %inst24 = load ptr, ptr null, align 8 + br label %bb25 + +bb25: ; preds = %bb23, %bb22 + store i8 1, ptr %arg3, align 1 + %inst26 = icmp eq i64 0, %inst11 + br i1 %inst26, label %bb28, label %bb22 + +bb27: ; preds = %bb28 + br i1 %arg8, label %bb31, label %bb13 + +bb28: ; preds = %bb28, %bb25 + %inst29 = load ptr, ptr null, align 8 + %inst30 = call i1 %inst29(ptr %arg2, i32 0, i32 0) + br i1 %arg9, label %bb27, label %bb28 + +bb31: ; preds = %bb72, %bb27 + br i1 %arg9, label %bb32, label %bb73 + +bb32: ; preds = %bb31 + br i1 %arg8, label %bb33, label %bb43 + +bb33: ; preds = %bb35, %bb32 + %inst34 = load ptr, ptr null, align 8 + br label %bb37 + +bb35: ; preds = %bb41 + %inst36 = icmp eq i64 0, %inst11 + br i1 %inst36, label %bb72, label %bb33 + +bb37: ; preds = %bb41, %bb33 + %inst38 = load i8, ptr %arg2, align 1 + %inst39 = icmp eq i8 %inst38, 0 + call void @hoge(ptr null, i32 0, i32 0) + br i1 %inst39, label %bb41, label %bb40 + +bb40: ; preds = %bb37 + store i32 0, ptr %arg1, align 4 + br label %bb41 + +bb41: ; preds = %bb40, %bb37 + %inst42 = icmp eq i64 0, 0 + br i1 %inst42, label %bb35, label %bb37 + +bb43: ; preds = %bb72, %bb32 + %inst44 = call i32 @hoge.3(ptr null, i32 0) + br label %bb45 + +bb45: ; preds = %bb52, %bb43 + %inst46 = load i8, ptr null, align 1 + %inst47 = icmp eq i8 %inst46, 0 + %inst48 = zext i32 %inst44 to i64 + %inst49 = getelementptr i8, ptr null, i64 %inst48 + %inst50 = load i8, ptr %inst49, align 1 + %inst51 = icmp eq i8 %inst50, 0 + br label %bb53 + +bb52: ; preds = %bb70 + br i1 %arg8, label %bb71, label %bb45 + +bb53: ; preds = %bb70, %bb45 + %inst54 = load i8, ptr null, align 1 + %inst55 = icmp eq i8 %inst54, 0 + invoke void @hoge(ptr %arg1, i32 0, i32 0) + to label %bb58 unwind label %bb56 + +bb56: ; preds = %bb69, %bb67, %bb66, %bb65, %bb64, %bb63, %bb60, %bb59, %bb58, %bb53 + %inst57 = landingpad { ptr, i32 } + cleanup + ret void + +bb58: ; preds = %bb53 + invoke void @hoge(ptr %arg1, i32 0, i32 0) + to label %bb59 unwind label %bb56 + +bb59: ; preds = %bb58 + invoke void @hoge(ptr %arg1, i32 0, i32 0) + to label %bb60 unwind label %bb56 + +bb60: ; preds = %bb59 + invoke void @hoge(ptr %arg1, i32 0, i32 0) + to label %bb61 unwind label %bb56 + +bb61: ; preds = %bb60 + %inst62 = or i1 %inst47, %inst55 + br i1 %inst62, label %bb64, label %bb63 + +bb63: ; preds = %bb61 + invoke void @hoge(ptr %arg1, i32 0, i32 0) + to label %bb64 unwind label %bb56 + +bb64: ; preds = %bb63, %bb61 + invoke void @hoge(ptr %arg1, i32 0, i32 0) + to label %bb65 unwind label %bb56 + +bb65: ; preds = %bb64 + invoke void @hoge(ptr %arg1, i32 0, i32 0) + to label %bb66 unwind label %bb56 + +bb66: ; preds = %bb65 + invoke void @hoge(ptr %arg1, i32 0, i32 0) + to label %bb67 unwind label %bb56 + +bb67: ; preds = %bb66 + invoke void @hoge(ptr %arg1, i32 0, i32 0) + to label %bb68 unwind label %bb56 + +bb68: ; preds = %bb67 + br i1 %inst51, label %bb70, label %bb69 + +bb69: ; preds = %bb68 + invoke void @hoge(ptr %arg1, i32 0, i32 0) + to label %bb70 unwind label %bb56 + +bb70: ; preds = %bb69, %bb68 + br i1 %arg9, label %bb52, label %bb53 + +bb71: ; preds = %bb52 + call void @llvm.lifetime.start.p0(i64 0, ptr null) + br label %bb72 + +bb72: ; preds = %bb71, %bb35 + br i1 %arg8, label %bb31, label %bb43 + +bb73: ; preds = %bb31 + %inst74 = call ptr @spam(ptr %arg) + unreachable +} + +declare ptr @zot.5() + +attributes #0 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } +attributes #1 = { cold } +attributes #2 = { minsize }