diff --git a/llvm/lib/CodeGen/MachineOutliner.cpp b/llvm/lib/CodeGen/MachineOutliner.cpp --- a/llvm/lib/CodeGen/MachineOutliner.cpp +++ b/llvm/lib/CodeGen/MachineOutliner.cpp @@ -618,9 +618,6 @@ F->setLinkage(GlobalValue::InternalLinkage); F->setUnnamedAddr(GlobalValue::UnnamedAddr::Global); - // FIXME: Set nounwind, so we don't generate eh_frame? Haven't verified it's - // necessary. - // Set optsize/minsize, so we don't insert padding between outlined // functions. F->addFnAttr(Attribute::OptimizeForSize); @@ -635,6 +632,12 @@ if (ParentFn.hasFnAttribute("target-features")) F->addFnAttr(ParentFn.getFnAttribute("target-features")); + // Set nounwind, so we don't generate eh_frame. + if (llvm::all_of(OF.Candidates, [](const outliner::Candidate &C) { + return C.getMF()->getFunction().hasFnAttribute(Attribute::NoUnwind); + })) + F->addFnAttr(Attribute::NoUnwind); + BasicBlock *EntryBB = BasicBlock::Create(C, "entry", F); IRBuilder<> Builder(EntryBB); Builder.CreateRetVoid(); diff --git a/llvm/test/CodeGen/AArch64/machine-outliner-retaddr-sign-cfi.ll b/llvm/test/CodeGen/AArch64/machine-outliner-retaddr-sign-cfi.ll --- a/llvm/test/CodeGen/AArch64/machine-outliner-retaddr-sign-cfi.ll +++ b/llvm/test/CodeGen/AArch64/machine-outliner-retaddr-sign-cfi.ll @@ -82,10 +82,8 @@ ; CHECK: [[OUTLINED_FUNC]] ; CHECK: // %bb.0: -; CHECK-NEXT: .cfi_b_key_frame ; V8A-NEXT: hint #27 ; V83A-NEXT: pacibsp -; CHECK-NEXT: .cfi_negate_ra_state ; V8A: hint #31 ; V83A: autibsp ; V8A-NEXT, V83A-NEXT: ret diff --git a/llvm/test/CodeGen/AArch64/machine-outliner-retaddr-sign-same-scope-same-key-b.ll b/llvm/test/CodeGen/AArch64/machine-outliner-retaddr-sign-same-scope-same-key-b.ll --- a/llvm/test/CodeGen/AArch64/machine-outliner-retaddr-sign-same-scope-same-key-b.ll +++ b/llvm/test/CodeGen/AArch64/machine-outliner-retaddr-sign-same-scope-same-key-b.ll @@ -72,10 +72,8 @@ ; CHECK-LABEL: OUTLINED_FUNCTION_0: ; CHECK: // %bb.0: -; CHECK-NEXT: .cfi_b_key_frame ; V8A-NEXT: hint #27 ; V83A-NEXT: pacibsp -; CHECK-NEXT: .cfi_negate_ra_state ; V8A: hint #31 ; V83A: autibsp ; CHECK-NEXT: ret diff --git a/llvm/test/CodeGen/AArch64/machine-outliner-retaddr-sign-v8-3.ll b/llvm/test/CodeGen/AArch64/machine-outliner-retaddr-sign-v8-3.ll --- a/llvm/test/CodeGen/AArch64/machine-outliner-retaddr-sign-v8-3.ll +++ b/llvm/test/CodeGen/AArch64/machine-outliner-retaddr-sign-v8-3.ll @@ -77,7 +77,6 @@ ; CHECK: OUTLINED_FUNC ; CHECK: // %bb.0: -; CHECK-NEXT: .cfi_b_key_frame ; CHECK-NEXT: pacibsp ; CHECK: retab ; CHECK-NOT: auti[a,b]sp diff --git a/llvm/test/CodeGen/AArch64/machine-outliner-throw.ll b/llvm/test/CodeGen/AArch64/machine-outliner-throw.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/machine-outliner-throw.ll @@ -0,0 +1,71 @@ +; RUN: llc -verify-machineinstrs -enable-machine-outliner -mtriple=aarch64-arm-none-eabi < %s | FileCheck %s +; RUN: llc -verify-machineinstrs -enable-machine-outliner -mtriple=aarch64-arm-none-eabi -stop-after=machine-outliner < %s | FileCheck %s -check-prefix=TARGET_FEATURES + +; Make sure that we haven't added nouwind. +; TARGET_FEATURES: define internal void @OUTLINED_FUNCTION_0() +; TARGET_FEATURES-SAME: #[[ATTR_NUM:[0-9]+]] +; TARGET_FEATURES: attributes #[[ATTR_NUM]] = { minsize optsize } + +define dso_local i32 @_Z5func1i(i32 %x) #0 { +; CHECK-LABEL: _Z5func1i: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: stp x30, x19, [sp, #-16]! // 16-byte Folded Spill +; CHECK-NEXT: .cfi_def_cfa_offset 16 +; CHECK-NEXT: .cfi_offset w19, -8 +; CHECK-NEXT: .cfi_offset w30, -16 +; CHECK-NEXT: orr w8, wzr, #0x1 +; CHECK-NEXT: madd w19, w0, w0, w8 +; CHECK-NEXT: mov w0, #4 +; CHECK-NEXT: bl __cxa_allocate_exception +; CHECK-NEXT: bl OUTLINED_FUNCTION_0 +entry: + %mul = mul nsw i32 %x, %x + %add = add nuw nsw i32 %mul, 1 + %exception = tail call i8* @__cxa_allocate_exception(i64 4) #1 + %0 = bitcast i8* %exception to i32* + store i32 %add, i32* %0, align 16 + tail call void @__cxa_throw(i8* %exception, i8* bitcast (i8** @_ZTIi to i8*), i8* null) #2 + unreachable +} + +define dso_local i32 @_Z5func2c(i8 %x) #0 { +; CHECK-LABEL: _Z5func2c: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: stp x30, x19, [sp, #-16]! // 16-byte Folded Spill +; CHECK-NEXT: .cfi_def_cfa_offset 16 +; CHECK-NEXT: .cfi_offset w19, -8 +; CHECK-NEXT: .cfi_offset w30, -16 +; CHECK-NEXT: and w8, w0, #0xff +; CHECK-NEXT: orr w9, wzr, #0x1 +; CHECK-NEXT: mov w0, #4 +; CHECK-NEXT: madd w19, w8, w8, w9 +; CHECK-NEXT: bl __cxa_allocate_exception +; CHECK-NEXT: bl OUTLINED_FUNCTION_0 +entry: + %conv = zext i8 %x to i32 + %mul = mul nuw nsw i32 %conv, %conv + %add = add nuw nsw i32 %mul, 1 + %exception = tail call i8* @__cxa_allocate_exception(i64 4) #1 + %0 = bitcast i8* %exception to i32* + store i32 %add, i32* %0, align 16 + tail call void @__cxa_throw(i8* %exception, i8* bitcast (i8** @_ZTIi to i8*), i8* null) #2 + unreachable +} + +; CHECK-LABEL: OUTLINED_FUNCTION_0: +; CHECK: .cfi_startproc +; CHECK: adrp x1, _ZTIi +; CHECK-NEXT: add x1, x1, :lo12:_ZTIi +; CHECK-NEXT: mov x2, xzr +; CHECK-NEXT: str w19, [x0] +; CHECK-NEXT: b __cxa_throw +; CHECK: .cfi_endproc + + +@_ZTIi = external dso_local constant i8* +declare dso_local i8* @__cxa_allocate_exception(i64) local_unnamed_addr +declare dso_local void @__cxa_throw(i8*, i8*, i8*) local_unnamed_addr + +attributes #0 = { minsize noreturn optsize } +attributes #1 = { nounwind } +attributes #2 = { noreturn } diff --git a/llvm/test/CodeGen/AArch64/machine-outliner-throw2.ll b/llvm/test/CodeGen/AArch64/machine-outliner-throw2.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/machine-outliner-throw2.ll @@ -0,0 +1,101 @@ +; RUN: llc -verify-machineinstrs -enable-machine-outliner -mtriple=aarch64-arm-none-eabi -frame-pointer=non-leaf < %s | FileCheck %s --check-prefix=NOOMIT +; RUN: llc -verify-machineinstrs -enable-machine-outliner -mtriple=aarch64-arm-none-eabi -frame-pointer=none < %s | FileCheck %s --check-prefix=OMITFP + +define void @_Z1giii(i32 %x, i32 %y, i32 %z) minsize { +; NOOMIT-LABEL: _Z1giii: +; NOOMIT: // %bb.0: // %entry +; NOOMIT-NEXT: b _Z1hiii +; +; OMITFP-LABEL: _Z1giii: +; OMITFP: // %bb.0: // %entry +; OMITFP-NEXT: b _Z1hiii +entry: + tail call void @_Z1hiii(i32 %x, i32 %y, i32 %z) + ret void +} + +declare void @_Z1hiii(i32, i32, i32) minsize + +define void @_Z2f1v() minsize { +; NOOMIT-LABEL: _Z2f1v: +; NOOMIT: // %bb.0: // %entry +; NOOMIT-NEXT: stp x29, x30, [sp, #-16]! // 16-byte Folded Spill +; NOOMIT-NEXT: mov x29, sp +; NOOMIT-NEXT: .cfi_def_cfa w29, 16 +; NOOMIT-NEXT: .cfi_offset w30, -8 +; NOOMIT-NEXT: .cfi_offset w29, -16 +; NOOMIT-NEXT: bl OUTLINED_FUNCTION_0 +; NOOMIT-NEXT: ldp x29, x30, [sp], #16 // 16-byte Folded Reload +; NOOMIT-NEXT: b _Z1giii +; +; OMITFP-LABEL: _Z2f1v: +; OMITFP: // %bb.0: // %entry +; OMITFP-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill +; OMITFP-NEXT: .cfi_def_cfa_offset 16 +; OMITFP-NEXT: .cfi_offset w30, -16 +; OMITFP-NEXT: bl OUTLINED_FUNCTION_0 +; OMITFP-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload +; OMITFP-NEXT: b _Z1giii +entry: + tail call void @_Z1giii(i32 1, i32 2, i32 3) + tail call void @_Z1giii(i32 1, i32 2, i32 3) + ret void +} + +define void @_Z2f2v() minsize { +; NOOMIT-LABEL: _Z2f2v: +; NOOMIT: // %bb.0: // %entry +; NOOMIT-NEXT: stp x29, x30, [sp, #-16]! // 16-byte Folded Spill +; NOOMIT-NEXT: mov x29, sp +; NOOMIT-NEXT: .cfi_def_cfa w29, 16 +; NOOMIT-NEXT: .cfi_offset w30, -8 +; NOOMIT-NEXT: .cfi_offset w29, -16 +; NOOMIT-NEXT: bl OUTLINED_FUNCTION_0 +; NOOMIT-NEXT: ldp x29, x30, [sp], #16 // 16-byte Folded Reload +; NOOMIT-NEXT: b _Z1giii +; +; OMITFP-LABEL: _Z2f2v: +; OMITFP: // %bb.0: // %entry +; OMITFP-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill +; OMITFP-NEXT: .cfi_def_cfa_offset 16 +; OMITFP-NEXT: .cfi_offset w30, -16 +; OMITFP-NEXT: bl OUTLINED_FUNCTION_0 +; OMITFP-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload +; OMITFP-NEXT: b _Z1giii +entry: + tail call void @_Z1giii(i32 1, i32 2, i32 3) + tail call void @_Z1giii(i32 1, i32 2, i32 3) + ret void +} + +; OMITFP-LABEL: OUTLINED_FUNCTION_0: +; OMITFP: .cfi_startproc +; OMITFP-NEXT: // %bb.0: +; OMITFP-NEXT: .cfi_def_cfa_offset 16 +; OMITFP-NEXT: .cfi_offset w30, -16 +; OMITFP-NEXT: str x30, [sp, #-16]! +; OMITFP-NEXT: mov w0, #1 +; OMITFP-NEXT: mov w1, #2 +; OMITFP-NEXT: mov w2, #3 +; OMITFP-NEXT: bl _Z1giii +; OMITFP-NEXT: mov w0, #1 +; OMITFP-NEXT: mov w1, #2 +; OMITFP-NEXT: mov w2, #3 +; OMITFP-NEXT: ldr x30, [sp], #16 +; OMITFP-NEXT: ret + +; NOOMIT-LABEL: OUTLINED_FUNCTION_0: +; NOOMIT: .cfi_startproc +; NOOMIT-NEXT: // %bb.0: +; NOOMIT-NEXT: .cfi_def_cfa_offset 16 +; NOOMIT-NEXT: .cfi_offset w30, -16 +; NOOMIT-NEXT: str x30, [sp, #-16]! +; NOOMIT-NEXT: mov w0, #1 +; NOOMIT-NEXT: mov w1, #2 +; NOOMIT-NEXT: mov w2, #3 +; NOOMIT-NEXT: bl _Z1giii +; NOOMIT-NEXT: mov w0, #1 +; NOOMIT-NEXT: mov w1, #2 +; NOOMIT-NEXT: mov w2, #3 +; NOOMIT-NEXT: ldr x30, [sp], #16 +; NOOMIT-NEXT: ret diff --git a/llvm/test/CodeGen/AArch64/machine-outliner.ll b/llvm/test/CodeGen/AArch64/machine-outliner.ll --- a/llvm/test/CodeGen/AArch64/machine-outliner.ll +++ b/llvm/test/CodeGen/AArch64/machine-outliner.ll @@ -9,6 +9,7 @@ ; TARGET_FEATURES-SAME: #[[ATTR_NUM:[0-9]+]] ; TARGET_FEATURES-DAG: attributes #[[ATTR_NUM]] = { ; TARGET_FEATURES-SAME: minsize +; TARGET_FEATURES-SAME: nounwind ; TARGET_FEATURES-SAME: optsize ; TARGET_FEATURES-SAME: "target-features"="+sse" @@ -103,4 +104,4 @@ ; CHECK-DAG: add sp, sp, #32 ; CHECK-DAG: ret -attributes #0 = { noredzone "target-cpu"="cyclone" "target-features"="+sse" } +attributes #0 = { nounwind noredzone "target-cpu"="cyclone" "target-features"="+sse" }