Skip to content

Commit 1cc8269

Browse files
yonghong-songYonghong Song
authored andcommitted
Automerge: [SelectionDAG] Not issue TRAP node if naked function (#132147)
In [1], Nikita Popov suggested that during lowering 'unreachable' insn should not generate extra code for naked functions, and this applies to all architectures. Note that for naked functions, 'unreachable' insn is necessary in IR since the basic block needs a terminator to end. This patch checked whether a function is naked function or not. If it is a naked function, 'unreachable' insn will not generate ISD::TRAP. [1] llvm/llvm-project#131731 Co-authored-by: Yonghong Song <[email protected]>
2 parents 590bc29 + 0ffe83f commit 1cc8269

File tree

7 files changed

+47
-37
lines changed

7 files changed

+47
-37
lines changed

llvm/include/llvm/IR/Instructions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4497,6 +4497,9 @@ class UnreachableInst : public Instruction {
44974497
return isa<Instruction>(V) && classof(cast<Instruction>(V));
44984498
}
44994499

4500+
// Whether to do target lowering in SelectionDAG.
4501+
bool shouldLowerToTrap(bool TrapUnreachable, bool NoTrapAfterNoreturn) const;
4502+
45004503
private:
45014504
BasicBlock *getSuccessor(unsigned idx) const {
45024505
llvm_unreachable("UnreachableInst has no successors!");

llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3143,21 +3143,12 @@ bool IRTranslator::translateVAArg(const User &U, MachineIRBuilder &MIRBuilder) {
31433143
return true;
31443144
}
31453145

3146-
bool IRTranslator::translateUnreachable(const User &U, MachineIRBuilder &MIRBuilder) {
3147-
if (!MF->getTarget().Options.TrapUnreachable)
3148-
return true;
3149-
3146+
bool IRTranslator::translateUnreachable(const User &U,
3147+
MachineIRBuilder &MIRBuilder) {
31503148
auto &UI = cast<UnreachableInst>(U);
3151-
3152-
// We may be able to ignore unreachable behind a noreturn call.
3153-
if (const CallInst *Call = dyn_cast_or_null<CallInst>(UI.getPrevNode());
3154-
Call && Call->doesNotReturn()) {
3155-
if (MF->getTarget().Options.NoTrapAfterNoreturn)
3156-
return true;
3157-
// Do not emit an additional trap instruction.
3158-
if (Call->isNonContinuableTrap())
3159-
return true;
3160-
}
3149+
if (!UI.shouldLowerToTrap(MF->getTarget().Options.TrapUnreachable,
3150+
MF->getTarget().Options.NoTrapAfterNoreturn))
3151+
return true;
31613152

31623153
MIRBuilder.buildTrap();
31633154
return true;

llvm/lib/CodeGen/SelectionDAG/FastISel.cpp

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1854,17 +1854,12 @@ bool FastISel::selectOperator(const User *I, unsigned Opcode) {
18541854
}
18551855

18561856
case Instruction::Unreachable: {
1857-
if (TM.Options.TrapUnreachable) {
1858-
if (TM.Options.NoTrapAfterNoreturn) {
1859-
const auto *Call =
1860-
dyn_cast_or_null<CallInst>(cast<Instruction>(I)->getPrevNode());
1861-
if (Call && Call->doesNotReturn())
1862-
return true;
1863-
}
1857+
auto UI = cast<UnreachableInst>(I);
1858+
if (!UI->shouldLowerToTrap(TM.Options.TrapUnreachable,
1859+
TM.Options.NoTrapAfterNoreturn))
1860+
return true;
18641861

1865-
return fastEmit_(MVT::Other, MVT::Other, ISD::TRAP) != 0;
1866-
}
1867-
return true;
1862+
return fastEmit_(MVT::Other, MVT::Other, ISD::TRAP) != 0;
18681863
}
18691864

18701865
case Instruction::Alloca:

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3501,19 +3501,10 @@ void SelectionDAGBuilder::visitIndirectBr(const IndirectBrInst &I) {
35013501
}
35023502

35033503
void SelectionDAGBuilder::visitUnreachable(const UnreachableInst &I) {
3504-
if (!DAG.getTarget().Options.TrapUnreachable)
3504+
if (!I.shouldLowerToTrap(DAG.getTarget().Options.TrapUnreachable,
3505+
DAG.getTarget().Options.NoTrapAfterNoreturn))
35053506
return;
35063507

3507-
// We may be able to ignore unreachable behind a noreturn call.
3508-
if (const CallInst *Call = dyn_cast_or_null<CallInst>(I.getPrevNode());
3509-
Call && Call->doesNotReturn()) {
3510-
if (DAG.getTarget().Options.NoTrapAfterNoreturn)
3511-
return;
3512-
// Do not emit an additional trap instruction.
3513-
if (Call->isNonContinuableTrap())
3514-
return;
3515-
}
3516-
35173508
DAG.setRoot(DAG.getNode(ISD::TRAP, getCurSDLoc(), MVT::Other, DAG.getRoot()));
35183509
}
35193510

llvm/lib/IR/Instructions.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4529,6 +4529,27 @@ UnreachableInst *UnreachableInst::cloneImpl() const {
45294529
return new UnreachableInst(Context);
45304530
}
45314531

4532+
bool UnreachableInst::shouldLowerToTrap(bool TrapUnreachable,
4533+
bool NoTrapAfterNoreturn) const {
4534+
if (!TrapUnreachable)
4535+
return false;
4536+
4537+
// We may be able to ignore unreachable behind a noreturn call.
4538+
if (const CallInst *Call = dyn_cast_or_null<CallInst>(getPrevNode());
4539+
Call && Call->doesNotReturn()) {
4540+
if (NoTrapAfterNoreturn)
4541+
return false;
4542+
// Do not emit an additional trap instruction.
4543+
if (Call->isNonContinuableTrap())
4544+
return false;
4545+
}
4546+
4547+
if (getFunction()->hasFnAttribute(Attribute::Naked))
4548+
return false;
4549+
4550+
return true;
4551+
}
4552+
45324553
FreezeInst *FreezeInst::cloneImpl() const {
45334554
return new FreezeInst(getOperand(0));
45344555
}

llvm/test/CodeGen/WebAssembly/naked-fn-with-frame-pointer.ll

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,11 @@ define dso_local void @naked() naked "frame-pointer"="all" {
99
; CHECK-32: .functype naked () -> ()
1010
; CHECK-32-NEXT: # %bb.0:
1111
; CHECK-32-NEXT: call main
12-
; CHECK-32-NEXT: unreachable
1312
;
1413
; CHECK-64-LABEL: naked:
1514
; CHECK-64: .functype naked () -> ()
1615
; CHECK-64-NEXT: # %bb.0:
1716
; CHECK-64-NEXT: call main
18-
; CHECK-64-NEXT: unreachable
1917
call void @main()
2018
unreachable
2119
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
; RUN: llc -o - %s -mtriple=x86_64-linux-gnu -trap-unreachable | FileCheck %s
2+
; RUN: llc -o - %s -mtriple=x86_64-linux-gnu -trap-unreachable -fast-isel | FileCheck %s
3+
4+
define dso_local void @foo() #0 {
5+
entry:
6+
tail call void asm sideeffect "movl 3,%eax", "~{dirflag},~{fpsr},~{flags}"()
7+
unreachable
8+
}
9+
; CHECK-NOT: ud2
10+
11+
attributes #0 = { naked }

0 commit comments

Comments
 (0)