With `--trap-unreachable`, `clang` can emit double `TRAP` instructions
for code that contains a call to `__builtin_trap()`:
```
> cat test.c
void test() { __builtin_trap(); }
> clang test.c --target=x86_64 -mllvm --trap-unreachable -O1 -S -o -
...
test:
...
ud2
ud2
...
```
`SimplifyCFGPass` inserts `unreachable` after a call to a `noreturn`
function, and later this instruction causes `TRAP/G_TRAP` to be emitted
in `SelectionDAGBuilder::visitUnreachable()` or
`IRTranslator::translateUnreachable()` if
`TargetOptions.TrapUnreachable` is set.
The patch checks the instruction before `unreachable` and avoids
inserting an additional trap.
30 lines
875 B
LLVM
30 lines
875 B
LLVM
; RUN: llc < %s -mtriple=i686-apple-darwin8 -mcpu=yonah | FileCheck %s -check-prefixes=CHECK,DARWIN
|
|
; RUN: llc < %s -mtriple=i686-unknown-linux -mcpu=yonah | FileCheck %s -check-prefixes=CHECK,LINUX
|
|
; RUN: llc < %s -mtriple=x86_64-scei-ps4 | FileCheck %s -check-prefixes=CHECK,PS4
|
|
; RUN: llc < %s -mtriple=x86_64-sie-ps5 | FileCheck %s -check-prefixes=CHECK,PS4
|
|
; RUN: llc < %s -mtriple=x86_64-windows-msvc | FileCheck %s -check-prefixes=CHECK,WIN64
|
|
|
|
; CHECK-LABEL: test0:
|
|
; CHECK: ud2
|
|
; CHECK-NOT: ud2
|
|
define i32 @test0() noreturn nounwind {
|
|
entry:
|
|
tail call void @llvm.trap( )
|
|
unreachable
|
|
}
|
|
|
|
; CHECK-LABEL: test1:
|
|
; DARWIN: int3
|
|
; LINUX: int3
|
|
; PS4: int $65
|
|
; WIN64: int3
|
|
; WIN64-NOT: ud2
|
|
define i32 @test1() noreturn nounwind {
|
|
entry:
|
|
tail call void @llvm.debugtrap( )
|
|
unreachable
|
|
}
|
|
|
|
declare void @llvm.trap() nounwind
|
|
declare void @llvm.debugtrap() nounwind
|